WPF,ObservableCollection / BindingList绑定到ListView

时间:2011-05-01 08:19:48

标签: c# wpf

我有将ObservableCollection绑定到LisView的问题。 问题是只有当我从ObservableCollection中添加/删除项目时,Binding才能正常工作。 但是当我在ObservableCollection中更改一个项的属性时,ListView仍然显示旧值。 我知道这是一个常见问题并且搜索了一个解决方案并且每个人都说我应该使用BindingList而不是ObservableCollectione,因为ObservableCollection不会传播PropertyChanged事件而BindingList会传播。所以我改为绑定列表,但问题仍然存在。

类别:

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);
    }
}

结合:

<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>

4 个答案:

答案 0 :(得分:7)

集合中的项目应该是实现INotifyPropertyChanged接口的类型。这样,您的列表视图将通知您单个项目对象中的属性值已更改。 ObservableCollection仅在集合更改(添加,删除项目等)时才会升起CollectionChanged事件。

引用来自ObservableCollection的MSDN库文章

  

完全支持传输数据   从绑定源对象到的值   绑定目标,你的每个对象   支持可绑定的集合   属性必须实现   适当的财产变了   通知机制如   INotifyPropertyChanged接口。

是的,如果你想把处理程序附加到你的子元素属性chnaged事件看看这个问题的答案怎么做,虽然问题有点不同但我认为答案将满足你的目的 - Observable Collection Property Changed on Item in the Collection

答案 1 :(得分:1)

您的媒体资源名为“姓名”,但您正在通知更改为“姓名”。这是区分大小写的。

答案 2 :(得分:1)

您的问题是您必须为名称

设置正确的属性名称

写:

 RaisePropertyChanged("Name"); 

而不是:

 RaisePropertyChanged("name"); 

答案 3 :(得分:0)

这与ObservableCollectionBindinglist无关,两者都可以在Layer实施INotifyPropertyChanged时发挥作用。只需更正绑定即可。将DataContext设置为网络实例,仅设置ItemsSource="{Binding Layers}"。现在,无论何时更改Name属性,它都会反映在ListView(已测试)中。