2

I have problem binding ObservableCollection to LisView. The problem is that Binding works fine only when I add/remove item from ObservableCollection. But when I change property of one item in ObservableCollection the ListView still shows old value. I know it's a common problem and searched for a solution and everybody say that I should use BindingList instead of ObservableCollectione because ObservableCollection does not propagate PropertyChanged events and BindingList does. So I changed to Binding List but the problem remains the same.

Class:

public class Network
{
    public class Layer : INotifyPropertyChanged
    {
        public enum ActivFunction { LINEAR, EXPONENTIAL, ARCUSTANGENT }

        private string name;

        public string Name
        {
            get
            {
                return name;
            }
            set 
            {
                name = value;
                RaisePropertyChanged("Name"); 
            }
        }

        public ActivFunction Activation { get; set; }
        public int Neurons { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void RaisePropertyChanged(String propertyName)
        {
            if ((PropertyChanged != null))
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

    public BindingList<Layer> Layers { get; set; }

    public Network()
    {
        Layers = new BindingList<Layer>();
    }

    public void AddLayer(Layer layer)
    {
        if (Layers.Count > 0)
        {
            int last = Layers.Count;
            Layers.Last().Name = "Layer " + last + " (hidden)";
        }
        Layers.Add(layer);
    }

    public void RemoveLayer(int index)
    {
        if( index >= 0 && index < Layers.Count )
            Layers.RemoveAt(index);
    }
}

Binding:

<ListView Grid.Row="0" x:Name="NetworkListview" ItemsSource="{Binding network.Layers}"
          IsSynchronizedWithCurrentItem="True">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="100" Header="layer name"
                            DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Width="60" Header="neurons"
                            CellTemplate="{StaticResource NeuronsTemplate}"/>
            <GridViewColumn Width="110" Header="activation"
                            CellTemplate="{StaticResource ActivationTemplate}"/>
        </GridView>
    </ListView.View>
</ListView>
user606521
  • 14,486
  • 30
  • 113
  • 204

4 Answers4

7

Items in your collection should be of type that implements INotifyPropertyChanged interface. This way your listview will be notified that property value in your single item object has changed. ObservableCollection rises CollectionChanged event only when collection changes (items added, removed, etc.)

Quote from the MSDN library article on ObservableCollection

To fully support transferring data values from binding source objects to binding targets, each object in your collection that supports bindable properties must implement an appropriate property changed notification mechanism such as the INotifyPropertyChanged interface.

And yeah in case you want to attach handlers to your child elements property chnaged event look at the answer for this question how to do it, although the question is bit different but the answer i think will served your purpose - Observable Collection Property Changed on Item in the Collection

Community
  • 1
  • 1
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185
1

Your property is called "Name" but you are notifying of a change to "name". It's case sensitive.

Russell Troywest
  • 8,635
  • 3
  • 35
  • 40
  • Nothing else jumps out as obviously wrong I'm afraid. As long as you're using the correct value in your PropertyChanged event and you are using an ObservableCollection I can't see what the problem is. I put some info on my blog to do with debugging bindings for myself and a colleague. You might find it useful in getting more info on what's happening. It's here http://rtroywest.wordpress.com/2011/03/02/debugging-xaml-bindings/ – Russell Troywest May 01 '11 at 12:14
1

Your problem is that you have to set the correct property name for the name

Write:

 RaisePropertyChanged("Name"); 

Instead of :

 RaisePropertyChanged("name"); 
Homam
  • 23,263
  • 32
  • 111
  • 187
  • This doesnt help. If fact I tried "Name" before and I changed to "name" to check if it helps. So the problem remains... – user606521 May 01 '11 at 09:09
  • 1
    Assuming you have another problem, you're binding with `Name` so, the passed property name should be `Name`. – Homam May 01 '11 at 09:12
  • 1
    Another thing, keep the ObservableCollection instead of BindingList, Have a look [here](http://stackoverflow.com/questions/4284663/difference-between-observablecollection-and-bindinglist/4284904#4284904) – Homam May 01 '11 at 09:15
0

This has nothing to do with ObservableCollection or Bindinglist, both will work as Layer is implementing INotifyPropertyChanged. Just correct the bindings. Set the DataContext to instance of Network and ItemsSource="{Binding Layers}" only. Now whenever you change the Name property it reflects in ListView (Tested).

Marko
  • 20,385
  • 13
  • 48
  • 64
Boxit
  • 1
  • 1