關於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