考虑一个案例,我有一个带有StudentView的WPF应用程序,该StudentView绑定到StudentViewModel中的属性(ObservableCollection)。我还有一个StudentService,它依赖于我的StudentRepository。 StudentService提供从UI以外的不同上下文调用的CRUD操作。
我的第一个实现在StudentService中有一个ObservableCollection。虽然它适用于异步调用和所有,但这个设置是从许多方面反击并且感觉不对。特别是在从各种上下文更新ObservableCollection时。
所以我认为更好的方法是将Observable保留在表示层(View / ViewModel)中,让StudentViewModel订阅来自StudentService的事件,然后在它们所在的上下文中更新Observable。
所以我的问题是,如果我的修改后的方法更好,或者可能还有更好的第三种选择?
使用示例进行编辑:
目前我有这个(简化但我认为重要的东西):
View显示学生列表,DataSource是我的ViewModel:
ItemsControl ItemsSource="{Binding Students.Result, UpdateSourceTrigger=PropertyChanged}">..</ItemsControl>
视图模型:
public class MainViewModel : ViewModelBase
{
public NotifyTaskCompletion<AsyncObservableCollection<Student>> Students { get; private set; }
public MainViewModel(IStudentService service)
{
Students = new NotifyTaskCompletion<AsyncObservableCollection<Student>>(service.List());
}
}
NotifyTaskCompletion来自Stephen Cleary的文章here。并且从here获取AsyncObservableCollection。
我的StudentService有这个界面:
public interface IStudentService
{
Task<bool> Add(Student student);
Task<AsyncObservableCollection<Student>> List();
}
从后台线程调用IStudentService.Add(...),必须在UI中发现它。
现在所有这些都有效,但AsyncObservableCollection锁定(我认为)存在一些问题。所以我想我需要从UI上下文锁定,但那只是感觉不对 - 必须在我的服务中引用UI。而我正在考虑的是拔出AsyncObservableCollection(这是ObservableCollection)并从我的服务中返回Task<IEnumerable<Student>>
- 并从服务中获取一些“OnStudentAdded”事件而不是......
希望这能让它更清楚吗?
感谢。
答案 0 :(得分:2)
每当添加或删除新项目时,服务都需要以某种方式通知视图模型。我同意最好通过从服务类引发事件或通过公开视图模型可以订阅的IObservable<T>
来做到这一点。
如果从视图直接绑定的服务公开公共ObservableCollection<T>
属性,则无法从服务类中的后台线程更新此集合。该服务在某种程度上依赖于客户端。
直接绑定到服务类公开的属性很少是个好主意。您可以在视图模型中创建集合的副本并绑定到此集合,但是您仍然需要将此集合与服务中定义的集合同步,这并不比订阅事件或{{1并手动更新数据绑定的源集合&#34;在视图模型中。