【问题标题】:Updating items inside ListBox更新 ListBox 内的项目
【发布时间】:2010-11-06 19:37:03
【问题描述】:

我有一个 ListBox 绑定到 DiceViewModel 的可观察集合。每当我单击按钮添加新项目时,ListBox 都会像我预期的那样显示新项目。到目前为止一切正常。

<ListBox
  ItemsSource="{Binding Path=AllDice}"
  DisplayMemberPath="Value"/>

但是,我还有另一个按钮可以滚动所有现有的骰子。框中已列出的项目不会更新,我不确定如何在保持 MVVM 设计模式的同时强制执行此操作。

另外,我的 DiceViewModel 已经实现了 INotifyPropertyChanged。

有什么建议吗?

【问题讨论】:

    标签: c# wpf mvvm binding viewmodel


    【解决方案1】:

    您需要在项目绑定到的集合上实现 INotifyCollectionChanged 接口,然后让它触发 CollectionChanged 事件以指示集合已更改。

    这将导致整个列表的刷新。

    【讨论】:

    • 好吧,我使用的 ObservableCollection 确实实现了 INotifyCollectionChanged,当我添加项目时 ListBox 确实添加了新条目,但是当基础项目数据的内容时它不会更新显示的值。
    【解决方案2】:

    经过更多的挖掘,这就是我发现的。 ObservableCollection 不会自动向我的 DiceViewModel 的 INotifyPropertyChanged 事件注册自身。因此不会处理任何属性更改。

    但是,有一种方法可以在 xaml 文件中进行:

    我将此命名空间定义添加到我的 Window 元素中。

    xmlns:vm="clr-namespace:Rolling.ViewModel"
    

    然后我修改了我的 ListBox 以使用具有指定 DataType 的 DataTemplate:

    <ListBox ItemsSource="{Binding Path=AllDice}">
      <ListBox.Resources>
        <DataTemplate DataType="{x:Type vm:DiceViewModel}">
          <TextBlock Text="{Binding Path=Value}"/>
        </DataTemplate>
      </ListBox.Resources>
    </ListBox>
    

    使用指定的 DataType,ObservableCollection 可以向我的集合项注册自己,接收它们的事件,然后触发它自己的 CollectionChanged 事件。

    我希望这可以帮助其他一些人了解这个记录不充分的功能。

    【讨论】:

    • 这可能是由于默认模板使用 ToString 的事实,并且您无法查看 ToString 的更改,因为它是一种方法。不错的皮卡。
    • 你知道,我回去做了一些实验。我删除了所有 DataTemplate 的东西并恢复到原始的简单代码......它仍然有效。我不太确定为什么它一开始就失败了。在搜索过程中的某个地方,我无意中解决了我原来的问题,并认为这篇文章的内容解决了它。
    【解决方案3】:

    在 ObservableCollection 的情况下,INotifyPropertyChanged 只会通知集合结构的变化,通常是添加和删除项目。集合不知道集合中单个项目的属性的更改。相反,单个项目本身负责发送其属性更改的通知。

    这背后的原因可以追溯到类责任和关注点分离。由于 DiceViewModel 可能具有与掷骰子相关的数据及其最后一次掷骰的值,因此它会在其自身属性发生变化时发送通知。

    【讨论】:

      猜你喜欢
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-26
      相关资源
      最近更新 更多