我没想到这会起作用,但我想尝试一下。我有一个bool应该告诉我用户是否在我的应用程序中选择了任何东西(在特定控件内)。
我想将某些内容绑定到那个bool:
private bool _isAnythingSelected;
public bool IsAnythingSelected
{
get
{
_isAnythingSelected = (MyModel.Series.Where(p => p.IsSelected && p.GetType() == typeof(LineSeries)).Count() > 0);
return _isAnythingSelected;
}
set
{
_isAnythingSelected = value;
RaisePropertyChanged("IsAnythingSelected");
}
}
这不符合我的意愿,我明白为什么会如此。我的问题是,如果不采用允许用户选择的每种方法,我应该如何实现这个选择?谢谢。
答案 0 :(得分:1)
要正确更新IsAnythingSelected
,您必须处理两种通知:
MyModel.Series
收集的通知已更改; MyModel.Series
集合项属性的通知已更改。第一个可以通过ObservableCollection<T>
(或任何其他实现INotifyCollectionChanged
的集合“开箱即用”实现。
第二个需要一个自定义解决方案(至少,我不知道任何现有的“开箱即用”)。
您可以将ObservableCollection<T>
与项目属性更改以这种方式结合使用:
class MyObservableCollection<T> : ObservableCollection<T>
where T : INotifyPropertyChanged
{
private void Initialize()
{
// initial PropertyChanged subscription
foreach (var item in Items)
{
SubscribeItemPropertyChanged(item);
}
}
private void SubscribeItemPropertyChanged(object item)
{
((INotifyPropertyChanged)item).PropertyChanged += HandleItemPropertyChanged;
}
private void UnSubscribeItemPropertyChanged(object item)
{
((INotifyPropertyChanged)item).PropertyChanged -= HandleItemPropertyChanged;
}
protected virtual void HandleItemPropertyChanged(object sender, PropertyChangedEventArgs args)
{
var handler = ItemPropertyChanged;
if (handler != null)
{
handler(sender, args);
}
}
protected override void ClearItems()
{
// we should unsubscribe from INotifyPropertyChanged.PropertyChanged event for each item
Items.ToList().ForEach(item => Remove(item));
}
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
base.OnCollectionChanged(e);
// subscribe for new items property changing;
// un-subscribe for old items property changing
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
SubscribeItemPropertyChanged(e.NewItems[0]);
break;
case NotifyCollectionChangedAction.Remove:
UnSubscribeItemPropertyChanged(e.OldItems[0]);
break;
case NotifyCollectionChangedAction.Replace:
SubscribeItemPropertyChanged(e.NewItems[0]);
UnSubscribeItemPropertyChanged(e.OldItems[0]);
break;
}
}
public MyObservableCollection()
: base()
{
}
public MyObservableCollection(IEnumerable<T> collection)
: base(collection)
{
Initialize();
}
public MyObservableCollection(List<T> list)
: base(list)
{
Initialize();
}
public EventHandler<PropertyChangedEventArgs> ItemPropertyChanged;
}
...并使MyModel.Series
成为MyObservableCollection<T>
个实例
然后,您的包含IsAnythingSelected
的类将如下所示:
// somewhere in code, where `MyModel` being initialized:
MyModel.Series.CollectionChanged += (sender, args) => RaisePropertyChanged("IsAnythingSelected");
MyModel.Series.ItemPropertyChanged += (sender, args) => RaisePropertyChanged("IsAnythingSelected");
public bool IsAnythingSelected
{
get
{
return MyModel.Series.Any(p => p.IsSelected && p.GetType() == typeof(LineSeries));
}
}
在这种情况下,您甚至不需要IsAnythingSelected
成为读写属性。只需通知,它已被更改,绑定引擎将重新读取其值。