c# – 使用MVVM更新相关属性
我的viewmodel的一些属性:
public ObservableCollection<Task> Tasks { get; set; } public int Count { get { return Tasks.Count; } } public int Completed { get { return Tasks.Count(t => t.IsComplete); } } 当任务更改时,更新这些属性的最佳方法是什么? 我目前的方法: public TaskViewModel() { Tasks = new ObservableCollection<Task>(repository.LoadTasks()); Tasks.CollectionChanged += (s,e) => { OnPropertyChanged("Count"); OnPropertyChanged("Completed"); }; } 有没有更优雅的方式来做到这一点? 解决方法
对于Count来说,你根本不用这样做.只需绑定到Tasks.Count,并且您的绑定将被ObservableCollection通知更改.
完成是一个不同的故事,因为这是在ObservableCollection之外.但是,从抽象/接口级别来看,您确实希望“完成”是“任务”集合的属性. 为此,我认为更好的方法是为您的Tasks属性创建“sub”视图模型: public class TasksViewModel : ObservableCollection<Task> { public int Completed { get { return this.Count(t => t.IsComplete); } } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); if(e.PropertyName == "Count") NotifyCompletedChanged(); } protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { base.OnCollectionChanged(e); NotifyCompletedChanged(); } void NotifyCompletedChanged() { OnPropertyChanged(_completedChangedArgs); } readonly PropertyChangedEventArgs _completedChangedArgs = new PropertyChangedEventArgs("Completed"); } 这给了ObservableCollection的所有好处,并且有效地使Completed属性成为它的一部分.我们仍然没有捕获完成项目数量真正改变的情况,但是我们已经减少了冗余通知的数量. 现在viewmodel只有属性: public TasksViewModel Tasks { get; set; } …并且您可以轻松绑定到任务,Tasks.Count和Tasks.Completed. 或者,如果您希望在“主”视图模型中创建这些其他属性,则可以使用这个概念来创建一个子类的ObservableCollection< T>使用某种方法创建一个可以传入Action< string>代表,将代表在主视图模型上提出属性更改通知,以及一些属性名称列表.然后,该集合可以有效地提高视图模型上的属性更改通知: public class ObservableCollectionWithSubscribers<T> : ObservableCollection<T> { Action<string> _notificationAction = s => { }; // do nothing,by default readonly IList<string> _subscribedProperties = new List<string>(); public void SubscribeToChanges(Action<string> notificationAction,params string[] properties) { _notificationAction = notificationAction; foreach (var property in properties) _subscribedProperties.Add(property); } protected override void OnPropertyChanged(PropertyChangedEventArgs e) { base.OnPropertyChanged(e); NotifySubscribers(); } protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { base.OnCollectionChanged(e); NotifySubscribers(); } void NotifySubscribers() { foreach (var property in _subscribedProperties) _notificationAction(property); } } 您甚至可以将属性类型保留为ObservableCollection< Task>. public class ViewModel : INotifyPropertyChanged { public ViewModel() { var tasks = new ObservableCollectionWithSubscribers<Task>(); tasks.SubscribeToChanges(Notify,"Completed"); Tasks = tasks; } public ObservableCollection<Task> Tasks { get; private set; } public int Completed { get { return Tasks.Count(t => t.IsComplete); } } public event PropertyChangedEventHandler PropertyChanged; void Notify(string property) { var handler = PropertyChanged; if(handler != null) handler(this,new PropertyChangedEventArgs(property)); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |