CoolStraw
CoolStraw

Reputation: 5390

Tricky WPF binding

I'm unable to do a simple but yet tricky WPF binding in Silverlight 4 (WP7 development)

I have the following code:

Class People{
    public string firstname;
    public string lastname;
}

Class DataSource{
    public static List<People> people; // consider this as a list filled with objects already
}

I'm trying to put the list of people into a ListBox, here's the xaml I've tried:

            <ListBox x:Name="peoplelistbox" Margin="0,0,-12,0" ItemsSource="{Binding DataSource.people}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                      <StackPanel Margin="0,0,0,17" Width="432">
                            <TextBlock Text="{Binding firstname}" TextWrapping="Wrap"/>
                            <TextBlock Text="{Binding lastname}" TextWrapping="Wrap"/>
                      </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

But unfortunately my listbox remains empty. What am I doing wrong ?

Thank you in advance :)

Cheers, Miloud B.

Upvotes: 2

Views: 1505

Answers (3)

Yogesh
Yogesh

Reputation: 14608

Firstly you are using fields, where you should use public property (i.e. people, firstname and lastname). Convert people to a public property, like this:

public static List<People> people { get; set; }

Then, you need to bind the ItemsSource using x:Static markup, like this:

<ListBox x:Name="peoplelistbox" Margin="0,0,-12,0">
   <ListBox.ItemsSource>
      <Binding Source="{x:Static local:DataSource.people}"/>
   <ListBox.ItemsSource/>
   ...

PS: local is the xml namespace pointing to your DataSource class's namespace. Also, your class too needs to be a public class.

EDIT:
For WP7, you need to declare the instance of the class in the resources and then you can use Path to point to the source. Like this:

<phone:PhoneApplicationPage.Resources>
    <local:DataSource x:Key="dataSource"/>
</phone:PhoneApplicationPage.Resources>
...
<ListBox x:Name="peoplelistbox" Margin="0,0,-12,0" ItemsSource="{Binding Source={StaticResource dataSource}, Path=people}">

PS: Again, your class needs to be public and must have a default constructor.

EDIT:
Here is a example which is working perfectly on my system. Check and see where are you making the mistake:

namespace WindowsPhoneApplication1
{
    public class People
    {
        public string firstname { get; set; }
        public string lastname { get; set; }
    }

    public class DataSource
    {
        public static List<People> people { get; set; }

        public DataSource() { }

        static DataSource()
        {
            people = new List<People> {new People {firstname = "Foo", lastname = "Bar"}};
        }
    }

    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
    }
}

Xaml (only the relevant portions):

...
...
xmlns:local="clr-namespace:WindowsPhoneApplication1"
...
...
<phone:PhoneApplicationPage.Resources>
    <local:DataSource x:Key="dataSource"/>
</phone:PhoneApplicationPage.Resources>
...
...
<ListBox x:Name="peoplelistbox" Margin="0,0,-12,0" ItemsSource="{Binding Source={StaticResource dataSource}, Path=people}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Margin="0,0,0,17" Width="432">
                <TextBlock Text="{Binding firstname}" TextWrapping="Wrap"/>
                <TextBlock Text="{Binding lastname}" TextWrapping="Wrap"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Upvotes: 5

brunnerh
brunnerh

Reputation: 184516

1.FirstName and LastName need to be public properties with at least getters.
2.Your list should also be a public property unless you explicitly set the DataContext of your Window
3.Need to either set the DataContext or reference the source otherwise.
4.You cannot bind to static properties like that, use {x:Static ...}.
5.This is not a tricky binding -.-

As devdigital said you might want to implement those interfaces as well.

Upvotes: 1

devdigital
devdigital

Reputation: 34349

You can only bind to properties, so change your public fields to properties.

Also, if you want your UI to update on programmatic changes to your people instances, then implement INotifyPropertyChanged on your People type (really that type should be called Person).

If you want your UI to update when items are added/removed from your DataSource people collection, then use ObservableCollection<T> rather than List<T>.

Upvotes: 0

Related Questions