【问题标题】:WPF, ObservableCollection/BindingList binding to ListViewWPF,ObservableCollection/BindingList 绑定到 ListView
【发布时间】:2011-05-01 08:19:48
【问题描述】:

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

类:

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>

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

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

    引自关于 ObservableCollection 的 MSDN 库文章

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

    是的,如果您想将处理程序附加到您的子元素属性更改事件,请查看这个问题的答案如何做到这一点,虽然问题有点不同,但我认为答案会达到您的目的 - Observable Collection Property Changed on Item in the Collection

    【讨论】:

      【解决方案2】:

      您的财产被称为“名称”,但您正在通知“名称”的更改。区分大小写。

      【讨论】:

      • 恐怕没有其他任何事情会因为明显的错误而跳出来。只要您在 PropertyChanged 事件中使用正确的值并且您使用的是 ObservableCollection,我就看不出问题出在哪里。我在我的博客上放了一些关于为我自己和同事调试绑定的信息。您可能会发现它有助于获取有关正在发生的事情的更多信息。在这里rtroywest.wordpress.com/2011/03/02/debugging-xaml-bindings
      【解决方案3】:

      您的问题是您必须为名称设置正确的属性名称

      写:

       RaisePropertyChanged("Name"); 
      

      而不是:

       RaisePropertyChanged("name"); 
      

      【讨论】:

      • 这没有帮助。如果事实上我之前尝试过“名称”,我改为“名称”以检查它是否有帮助。所以问题仍然存在......
      • 假设你有另一个问题,你绑定Name所以,传递的属性名称应该是Name
      • 还有一点,保留 ObservableCollection 而不是 BindingList,看看here
      【解决方案4】:

      这与ObservableCollectionBindinglist 无关,两者都将在Layer 实现INotifyPropertyChanged 时工作。只需更正绑定即可。将 DataContext 设置为 Network 实例,并且仅将 ItemsSource="{Binding Layers}" 设置为。现在,每当您更改 Name 属性时,它都会反映在 ListView(已测试)中。

      【讨论】:

        猜你喜欢
        • 2017-09-29
        • 1970-01-01
        • 1970-01-01
        • 2011-06-20
        • 1970-01-01
        • 2011-09-09
        • 1970-01-01
        • 2012-05-26
        • 2018-05-21
        相关资源
        最近更新 更多