2014-02-14 83 views
4

当不可观察时绑定对象的列表属性是否有最佳实践方法?例如,如果我们有:当属性不​​可观察时绑定

public class Band 
{ 
    public string Name { get; set; } 
    public List<Musician> Members { get; private set; } 
    // other properties here 
} 

如果我的视图模型具有Band财产,我想我的UI绑定到Members财产,如何在用户界面上显示更新到Members财产?成员不可观察。

目前的想法是创建一个DTO,它是Band类的精确副本,但是使MembersObservableCollection。然后UI将绑定到这个DTO。在视图模型关闭之前,它会将DTO映射回适当的Band类。这似乎是一个开销。有没有更好的办法?

编辑 - 另一种选择

我只是进行了座谈,在人,用别人这件事。这个想法是在视图模型上添加一个ObservableCollection属性。然后,在视图模型的构造函数中,使用实体来填充ObservableCollection。用户完成编辑后,使用更新的ObservableCollection重置实体上的List

+0

我打算建议在ViewModel中放置可观察属性,但是从编辑中可以看出,您已经在实现这一目标。毕竟,ViewModel是为了模型化视图,所以应该在可观察的属性在一个完美的MVVM世界:) – Rachel

回答

2

正如您所提到的,您可以使用ObservableCollection。您也可以使用BindingList

如果你不想去的路线,另一个另一种选择我看到的是使Band实施INotifyPropertyChanged,然后用你的财产Members调用namePropertyChanged。这将告诉消费者控制该列表已更新并自行刷新。

与该路线相关的问题是,尝试和计算何时调用PropertyChanged事件的难度可能比仅将您的集合更改为ObservableCollection<T>BindingList<T>更痛苦。

最后一种选择是在每次您认为更改或者控件支持时重新绑定集合,请调用可用的Refresh方法。某处某处必须告诉控制系统,因为它们不会定期检查,所以系统会发生变化。

因为您将此标记为MVVM,所以您的视图应该有BandViewModel和ObservableCollection为MemberViewModel s。 ViewModel中的所有内容都应该是可绑定的,并在发生更改时发送通知。

+0

也有一个选项可以在默认视图中调用Refresh。 (即'CollectionViewSource.GetDefaultView(Members).Refresh()') – zahir

+0

@zahir真。我会更新我的答案也反映了这一点。 – TyCobb

+0

如果我做了您的第一个建议(ObservableCollection或BindingList),那意味着更改我的域实体以遵守UI需求,所以我宁愿不这样做。现在检查其余的。 –

0

你的编辑让问题更加混乱。回答为什么应该使用ObservableCollection。

当你想让你的UI观察这个集合时,你应该使用ObservableCollection。我的意思是,当你希望修改这个集合(不是在谈论这个集合中的项目,而是整个集合)。如果你希望添加/删除/排序/过滤这个集合...如果没有这些操作是预期的,那么你也很好地绑定到IEnumerable!

另请注意,基础项目中的属性被修改与你如何将集合绑定为(IEnumerable或Observable)无关。如果基础类型引发适当的通知更改事件(并实现INotifyPropertyChanged),则会反映(或不反映)基础项目属性的更新。

希望有帮助!