WPF data binding to collection object

Arg, although I was googling, I really would appreciate it if someone could break my problem, since all the code examples on the Internet confuse me more than they help (maybe it's only too late) ...

I have a simple class as defined below:

public class Person { int _id; string _name; public Person() { } public int ID { get { return _id; } set { _id = value; } } public string Name { get { return _name; } set { _name = value; } } } 

which is stored in the database, and after a bit more code, I put it in the ObservableCollection object to try to bind the data in WPF later:

  public class People : ObservableCollection<Person> { public People() : base() { } public void Add(List<Person> pListOfPeople) { foreach (Person p in pListOfPeople) this.Add(p); } } 

In XAML, I have a ListView that I would like to populate with a ListViewItem (consisting of a text block) for each element of the People object as it is being updated from the database. I would also like this text block to bind to the Name property of the Person object.

At first I thought I could do this:

 lstPeople.DataContext = objPeople; 

where lstPeople is my ListView control in my XAML, but that of course does nothing. I found TONS of examples online where people through XAML create an object and then bind it through their XAML; but not where we attach to the instantiated object and rewrite accordingly.

Can someone please give me some pointers to:

A) How do I link a ListView control to my People object instance?

B) How can I apply a template to my ListView to format it for objects in the collection?

Even links to a decent example (not one working on an object declared in XAML, please) will be appreciated.

Thank you for your time.

+6
collections data-binding wpf
source share
3 answers

You were so close.

 lstPeople.ItemsSource = objPeople; // :) 

The only thing you need is how to apply the view to each element in your collection. No problems. I will not use ListView ... I just use ItemControl because it is a little easier.

 <ItemsControl x:Name="lstPeople"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> 

This is pretty much the case. The strategy for Listview is the same, but you need to provide a little more XAML to create column headers, etc. At the moment, I'm not sure that you need it, so I left it.

Edit: This uses the extension method for AddRange, which will do what you are trying to do by subclassing the ObservableCollection. A little easier ... especially if you have many types of collections (you will)

 public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items) { foreach(var item in items) { collection.Add(item); } } 

Then you can simply do:

 ObservableCollection<Person> peeps = new ObservableCollection<Person>(); peeps.AddRange(new List<Person> { new Person() { Name = "Greg" }, new Person() { Name = "Joe" } }); 
+6
source share

@ Anderson beat me in seconds, my answer was very similar.

One thing I will add: there is no need to define a new type of collection that inherits from ObservableCollection, instead you can just do this:

 ObservableCollection<Person> myPeopleCollection = new ObservableCollection<Person>(); 

The only time you want to extend it is if you are going to do something else or pretend that you do not seem to be doing.

0
source share

Indeed, the answer to Anderson Eames is correct (up), although I have two points:

Firstly, if you need to display only one property of an object, I find it easier and cleaner to use a ListBox instead of a ListView , because the code for binding the property will be reduced to

 <ListBox x:Name="lstPeople" DisplayMemberPath="Name" /> 

Secondly, if you use WPF and Binding, make sure your objects implement INotifyPropertyChanged , so changes are always synchronized between the user interface and the objects.

 public class Person : INotifyPropertyChanged { int _id; string _name; public Person() { } public int ID { get { return _id; } set { _id = value; RaisePropertyChanged("ID"); } } public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } } pivate void RaisePropertyChanged(string propName) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } 
0
source share

All Articles