none
How to make a custom collection bindable RRS feed

  • Question

  • Let's say I have a person class that looks like the following:

    namespace CustomCollectionBinding
    
    {
    
    	public class Person : INotifyPropertyChanged
    
    	{
    
    
    
    		#region INotifyPropertyChanged Members
    
    
    
    		public event PropertyChangedEventHandler PropertyChanged;
    
    
    
    		protected void RaisePropertyChanged(string propertyName)
    
    		{
    
    			if (PropertyChanged != null)
    
    			{
    
    				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    
    			}
    
    		}
    
    
    
    		#endregion
    
    
    
    		private string name;
    
    
    
    		public string Name
    
    		{
    
    			get { return name; }
    
    			set
    
    			{
    
    				name = value;
    
    				this.RaisePropertyChanged("Name");
    
    			}
    
    		}
    
    
    
    		private double height;
    
    		public double Height
    
    		{
    
    			get { return height; }
    
    			set
    
    			{
    
    				height = value;
    
    				this.RaisePropertyChanged("Height");
    
    			}
    
    		}
    
    
    
    		private double weight;
    
    		public double Weight
    
    		{
    
    			get { return weight; }
    
    			set
    
    			{
    
    				weight = value;
    
    				this.RaisePropertyChanged("Weight");
    
    			}
    
    		}
    
    
    
    	}
    
    }
    
    
    This works out just fine and good to use with WPF bindings. However I need to have a collection of these be displayed and bound. Once again not a problem I can just use ObservableCollection<Person>.  However, in my particular project I need to be able to have a few other properties available for reporting purpose, such as the total height and total weight of all the people in the collection.  Now I would like to design this correctly so I wanted to make a custom collection that would have these two properties. This class looks like the following:

    namespace CustomCollectionBinding
    
    {
    
    	public class PersonCollection : INotifyCollectionChanged, INotifyPropertyChanged
    
    	{
    
    		private List<Person> persons;
    
    
    
    		public PersonCollection()
    
    		{
    
    			persons = new List<Person>();
    
    		}
    
    
    
    		public Person this[int index]
    
    		{
    
    			get { return persons[index]; }
    
    			set { persons[index] = value; }
    
    		}
    
    
    
    		public void Add(Person person)
    
    		{
    
    			//Code for add
    
    		}
    
    
    
    		public bool Remove(Person person)
    
    		{
    
    			//code for remove
    
    			return true;
    
    		}
    
    
    
    		public int TotalHeight
    
    		{
    
    			get
    
    			{
    
    				//Logic for total height
    
    				return 0;
    
    			}
    
    		}
    
    
    
    		public int TotalWeight
    
    		{
    
    			get
    
    			{
    
    				//Logic for total weight
    
    				return 0;
    
    			}
    
    		}
    
    
    
    		#region INotifyPropertyChanged Members
    
    
    
    		public event PropertyChangedEventHandler PropertyChanged;
    
    
    
    		protected void RaisePropertyChanged(string propertyName)
    
    		{
    
    			if (PropertyChanged != null)
    
    			{
    
    				PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    
    			}
    
    		}
    
    
    
    		#endregion
    
    
    
    		public event NotifyCollectionChangedEventHandler CollectionChanged;
    
    	}
    
    }
    
    
    The part where I'm lost is what else I need to do to PersonCollection to make it so I can bind a ListBox items to a PersonCollection object the same way I would bind a ListBox items to a ObservableCollection<T>.

    Does anyone know how to do this?
    Friday, August 7, 2009 12:14 AM

Answers

  • You will need implement IEnumerable<Person>, that is all that WPF need to make something bindable.
    In fact if you don't need notifications, you can remove the implementation of INotifyCollectionChanged and IPropertyChanged from PersonCollection, however if you need notifications in the collection you will need CollectionChanged and PropertyChanged events from the Add and Remove methods.
    http://weblogs.asp.net/marianor/
    • Marked as answer by CT2049 Monday, August 10, 2009 12:50 PM
    Friday, August 7, 2009 2:27 AM

All replies

  • You will need implement IEnumerable<Person>, that is all that WPF need to make something bindable.
    In fact if you don't need notifications, you can remove the implementation of INotifyCollectionChanged and IPropertyChanged from PersonCollection, however if you need notifications in the collection you will need CollectionChanged and PropertyChanged events from the Add and Remove methods.
    http://weblogs.asp.net/marianor/
    • Marked as answer by CT2049 Monday, August 10, 2009 12:50 PM
    Friday, August 7, 2009 2:27 AM
  • Hi CT2049,

    Why not derive your new collection directly from the ObservableCollection<T> class? Thus, you only need to add two properties for the TotalHeight and TotalWeight in the derived collection. For example:

    public class MyCollection<T>:ObservableCollection<T>
    {
       public int TotalHeight
       {
         get
         {
           //Logic for total height
           return 0;
         }
       }

      public int TotalWeight
      {
        get
        {
           //Logic for total weight
           return 0;
        }
       }
     }

    Hope thiis helps.

    Sincerely,
    Linda Liu


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Monday, August 10, 2009 6:05 AM