WP7:我可以在ViewModel中使用IEnumerable而不是ObservableCollection吗?

时间:2011-03-02 09:20:27

标签: mvvm windows-phone-7

我是WP7 dev的新手,我正在尝试使用数据绑定。我有一个xml文件,我想在列表框中表示它。我创建了一个ModelView,我在其上创建了一个Linq查询,其结果我想放在一个列表框中。我已经看到很多DataBinding的例子使用了ObservableCollection类......我想用Linq来获取结果而不是逐行循环,但是如果我使用IEnumerable而不是ObservableCollection,那么DataBinding不起作用......那是正常的吗?

提前致谢和问候 C。

4 个答案:

答案 0 :(得分:1)

Silverlight处理属性更改机制,以便在属性发生更改时通知以更新数据绑定。您可以使用依赖项属性(对于视图模型极不可能),也可以在视图模型类中实现INotifyPropertyChanged接口。

ObservableCollection的情况下,当它的内容发生更改(添加/删除/插入)时,它实际上会引发CollectionChanged事件,这也会提示数据绑定更新。在您的情况下,通过绑定到IEnumerable,数据绑定机制不知道内容何时发生更改,因为没有引发事件。

如果每个操作都会生成一个新列表,那么每次重新查询时都不会通过创建ObservableCollection来获取任何内容。因此,当您重新查询时,您需要implement the INotifyPropertyChanged interface并为yrou IEnumerable属性提出属性更改通知。

如果每次重新查询时都有要添加/删除的项目,那么第一次创建ObservableCollection然后在每个查询上调用Add / Remove都可以正常工作

答案 1 :(得分:0)

我想它必须是IList才能工作。 IEnumerable无效。

尝试在.ToList()查询中添加LINQ,将其转换为List<T>

对于ObservableCollection<T>,如果您计划更改该集合中的项目,则需要使用它,以便UI自动刷新。

答案 2 :(得分:0)

您可以通过将其传递给OC的其中一个构造函数,从枚举中创建ObservableCollection

ObservableCollection<Foo> x = new ObservableCollection<Foo>(enumerable); 

Cast LINQ result to ObservableCollection提供

当然,这只适用于您希望自己避免循环浏览记录并且由于代码中的行为而没有理由。

答案 3 :(得分:0)

  

但如果我使用IEnumerable而不是ObservableCollection,则DataBinding不起作用

使用IEnumerable作为数据项列表不是问题,事实上ItemsSourceListBox属性的定义是:

public IEnumerable ItemsSource { get; set; }

最有可能的问题是,您的属性在其值发生更改时未通知(使用INotifyPropertyChanged接口)。

ObservableCollection类型是一个实现INotifyCollectionChanged的集合,因此您可以轻松判断集合本身何时发生更改,但是当集合项本身的属性发生更改时,这不会通知您。它还实现了INotifyPropertyChanged,这很可能是您的数据绑定在ViewModel中对您的属性起作用的原因。在这种情况下ObservableCollection很好用的原因是因为您只需向集合中添加和删除项以更新基于列表的控件,您不必重新绑定它(或重建列表)。

因此,如果绑定到IEnumerable<>属性,请确保引发属性已更改的通知,并注意添加/删除单个项目不会自动反映在UI中,除非您设计出一种方式通知绑定属性已经改变(这将是一个黑客攻击)。