ceth
ceth

Reputation: 45285

Bind collection of objects to ListBox

I have class Person:

    public class Person : INotifyPropertyChanged
    {

        private String name = "";
        public event PropertyChangedEventHandler PropertyChanged;

        public Person()
        {
            NameProperty = "hi";
        }

        public Person(String _name)
        {
            NameProperty = _name;
        }

        public String NameProperty
        {
            get { return name; }
            set 
            { 
                name = value;
                OnPropertyChanged("NameProperty");
            }
        }

        public override String ToString()
        {
            return NameProperty;
        }

        protected void OnPropertyChanged(string name)
        {

            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }

        }

    }

And I can bind the instance of my class to TextBox:

myPerson = new Person("demas");
Binding myBinding = new Binding("NameProperty");
myBinding.Source = myPerson;
txtName.SetBinding(TextBox.TextProperty, myBinding);

Now I have collection of my class and want to bind it to ListBox:

List<Person> myCollection = new List<Person>(); // on the MainWindow level

myCollection.Add(new Person("one"));
myCollection.Add(new Person("two"));
myCollection.Add(new Person("three"));

So I have to see in the ListBox three values: one, two, three. How can I do it?

Upvotes: 2

Views: 6310

Answers (2)

Douglas
Douglas

Reputation: 54877

Expose your collection as a public property in your MainWindow. If you want your ListBox to get updated when elements are added or removed to your collection, you should use an ObservableCollection<T> rather than List<T>.

readonly ObservableCollection<Person> myCollection = new ObservableCollection<Person>();

public ObservableCollection<Person> MyCollection
{
    get { return myCollection; }
} 

Then, in your XAML, use data binding to reference the property:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:l="clr-namespace:WpfApplication1"
        xmlns:p="clr-namespace:WpfApplication1.Properties"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox ItemsSource="{Binding MyCollection}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding NameProperty}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

Don’t forget to set the DataContext either on your ListBox or on its parent window.

P.S. Identifier names should identify the purpose, not the type. Use Persons instead of MyCollection; use Name instead of NameProperty.

Upvotes: 6

Hadi Eskandari
Hadi Eskandari

Reputation: 26354

Use ObservableCollection instead of List. That will update the UI when you add/remove items to/from the collection. Once you have the collection, bind it to ItemsSource property of the ListBox.

Additionally you can control how Person objects are rendered on the UI by either overriding the ToString method on Person class or setting an ItemTemplate on ListBox control.

Upvotes: 3

Related Questions