关于Count
,你根本不需要这样做。只需绑定到Tasks.Count
,您的绑定将通过ObservableCollection
得到通知。
Completed
是一个不同的故事,因为这是ObservableCollection
之外。尽管如此,从抽象/界面的层面来看,你真的想要Completed
成为该集合的一个属性。
对于这一点,我认为更好的方法是创建“子”视图模型为您Tasks
属性:
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
属性部分。我们仍然没有捕捉到完成项目数量真正发生变化的情况,但我们已经在一定程度上减少了冗余通知的数量。
现在视图模型只是有属性:
public TasksViewModel Tasks { get; set; }
...你可以绑定到Tasks
,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));
}
}
来源
2011-06-11 02:46:32
Jay
这当然是一个更好的设计。 – 2011-06-11 02:52:12