由于我是WPF和MVVM的新手,这可能是非常明显和微不足道的事情,所以请耐心等待。
无论如何,我有一个具有这些属性的视图模型:
class ViewModel : INotifyPropertyChanged {
ICollectionView Items; // a list of Items object, wraps _items field, each Item has a Date property
string Filter; // a filter key, wraps _filter field and calls ApplyFilter() as it is changed
void ApplyFilter(); // based on the filter key, _items.Filter gets set to some predicate
}
属性会在设置时引发PropertyChanged事件以及所有常见的MVVM内容。 在视图中,我有一个简单的ItemsControl,它绑定到Items属性,还有一些奇特的数据模板来显示每个Item。
已经请求显示按天分组的项目,以便您查看每天的日期标题以及Date属性与标题中的日期对应的项目列表。
由于这严格来说是一个显示问题,我决定保留视图模型,但是使用转换器将ICollectionView项转换为字典,其中键是日期,集合是Items的子集那个日期。
ItemsControl现在有一个带有TextBlock的StackPanel来显示日期标题(字典键)和另一个ItemsControl,它基本上是旧版本的副本,它只列出了项目(字典值)。
视图渲染效果很好,但过滤器不再有效。由于控件绑定到Items,并且ICollectionView实现了INotifyCollectionChanged,我期望过滤器在更改Items列表时工作,并且转换器将重新运行以重建字典。嗯,事实并非如此。更改过滤器会调用ApplyFilter(),_items.Filter将设置为所需的谓词,但视图永远不会更改。我也试过从ApplyFilter调用PropertyChanged for Items,但这也不起作用。
显然,我设计的方法应该如何运作是错误的,说实话我是出于想法,除了创建新的对象,将项目的日期和列表保存为属性,然后使用其中的列表VM。但是,正如我所说,在我看来,这只是一个视图问题,所以模型只需要提供一个项目列表,视图有责任决定如何呈现它们。
非常感谢任何帮助,并提前感谢。
编辑: 现在我想如果我正在更改_filter.Filter,那么Items的PropertyChanged事件实际上从未被引发,因为它实际上没有改变(内部已经改变,但是项目本身仍然是相同的ICollectionView) 。 因此,永远不会再次触发转换器。
如果是这种情况,我该如何触发转换器?
后,在执行ApplyFilter()之后提升Item的PropertyChanged也没有做任何事情。答案 0 :(得分:1)
也许使用ListView而不是简单的ItemsControl +转换器是更好的主意? ListView有很多很好的功能。如虚拟化,分组等 您所要做的就是修改ICollectionView分组属性并应用模板(GroupStyle)
至于你的问题,你当前的行为对我有意义。如果你想转换器重新运行,你应该创建新的方法RefreshBinding()并做这样的事情;
var referenceCopy = Items;
Items = null;//make sure INotifyPropertyCHanged is fired.
Items = referenceCopy; //converter should be called again.
在您需要重新运行转换器后,您将调用它。但说实话,只需使用ICollectionView + Grouping属性和ListView。或者您可以自己实现ListView功能。使用转换器似乎不是很好的解决方案。