简体   繁体   English

WPF,ObservableCollection/BindingList 绑定到 ListView

[英]WPF, ObservableCollection/BindingList binding to ListView

I have problem binding ObservableCollection to LisView.我在将 ObservableCollection 绑定到 LisView 时遇到问题。 The problem is that Binding works fine only when I add/remove item from ObservableCollection.问题是绑定只有在我从 ObservableCollection 添加/删除项目时才能正常工作。 But when I change property of one item in ObservableCollection the ListView still shows old value.但是当我更改 ObservableCollection 中一项的属性时,ListView 仍然显示旧值。 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.我知道这是一个常见问题并寻找解决方案,每个人都说我应该使用 BindingList 而不是 ObservableCollectione,因为 ObservableCollection 不会传播 PropertyChanged 事件而 BindingList 会。 So I changed to Binding List but the problem remains the same.所以我改为绑定列表,但问题仍然存在。

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

Items in your collection should be of type that implements INotifyPropertyChanged interface.集合中的项目应该是实现 INotifyPropertyChanged 接口的类型。 This way your listview will be notified that property value in your single item object has changed.这样,您的列表视图将被通知您的单个项目 object 中的属性值已更改。 ObservableCollection rises CollectionChanged event only when collection changes (items added, removed, etc.) ObservableCollection 仅在集合更改(添加、删除项目等)时引发 CollectionChanged 事件

Quote from the MSDN library article on ObservableCollection引自关于 ObservableCollection 的 MSDN 库文章

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.为了完全支持将数据值从绑定源对象传输到绑定目标,集合中支持可绑定属性的每个 object 都必须实现适当的属性更改通知机制,例如 INotifyPropertyChanged 接口。

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是的,如果您想将处理程序附加到您的子元素属性 chnaged 事件,请查看这个问题的答案如何做到这一点,虽然问题有点不同,但我认为答案将满足您的目的 - Observable Collection Property Changed on Item在收藏中

Your property is called "Name" but you are notifying of a change to "name".您的财产被称为“名称”,但您正在通知“名称”的更改。 It's case sensitive.它区分大小写。

Your problem is that you have to set the correct property name for the name您的问题是您必须为名称设置正确的属性名称

Write:写:

 RaisePropertyChanged("Name"); 

Instead of:代替:

 RaisePropertyChanged("name"); 

This has nothing to do with ObservableCollection or Bindinglist , both will work as Layer is implementing INotifyPropertyChanged .这与ObservableCollectionBindinglist ,两者都将在 Layer 实现INotifyPropertyChanged时工作。 Just correct the bindings.只需更正绑定即可。 Set the DataContext to instance of Network and ItemsSource="{Binding Layers}" only.仅将DataContext设置为 Network 和ItemsSource="{Binding Layers}"的实例。 Now whenever you change the Name property it reflects in ListView (Tested).现在,每当您更改 Name 属性时,它都会反映在ListView (已测试)中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM