订阅 ObservableCollection 项目 属性 已更改 - WPF
Subscribe to ObservableCollection item property changed - WPF
我需要订阅列表中某个对象的 属性。我找到了这个示例 (),它工作得很好,但是如果我向列表中添加一个新元素,它就不起作用。任何解决方案?谢谢!
编辑
IDisposable subscription =
Observable
.FromEventPattern
<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
x => MyList.CollectionChanged += x,
x => MyList.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
.SelectMany(x =>
{
CallMethodWhenAddItem(x);
return x.OnPropertyChange(nameof(x.MyCustomProperty));
})
.Subscribe(x =>
// x is PropertyChangedEventArgs, not MyCustomClass
if (x.MyCustomProperty == "SomeValue") {
RunAction();
}
});
public static IObservable<PropertyChangedEventArgs> OnPropertyChange<T>(this T currentSource, string propertyName)
where T : INotifyPropertyChanged
{
return
Observable
.FromEventPattern
<PropertyChangedEventHandler, PropertyChangedEventArgs>(
eventHandler => eventHandler.Invoke,
x => currentSource.PropertyChanged += x,
x => currentSource.PropertyChanged -= x)
.Where(x => x.EventArgs.PropertyName == propertyName)
.Select(x => x.EventArgs);
}
你能用以下问题指导我吗?
1) 使用"eventHandler => eventHandler.Invoke"和不使用有什么区别。互联网上的许多示例都使用了它,而其他示例则没有。我真的看不出有什么不同。
2) 我如何退订已添加 "dynamically" 的 属性。将其从列表中删除?
谢谢!
System.Func<EventHandler<TEventArgs>, TDelegate>
参数用于将给定的事件处理程序转换为与底层 .NET 事件兼容的委托。如果不需要 - 不要使用它。它实际上用于连接非标准事件处理程序。
您永远不应该进行嵌套订阅。这样你就永远不需要担心处理内部订阅。像这样写您的查询:
IDisposable subscription =
Observable
.FromEventPattern
<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
x => MyList.CollectionChanged += x,
x => MyList.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
.SelectMany(x =>
{
CallMethodWhenAddItem(x);
return x.OnPropertyChange(nameof(x.MyCustomProperty));
})
.Subscribe(_ => { });
根据评论更新:
void Main()
{
var MyList = new ObservableCollection<int>();
IDisposable subscription =
Observable
.FromEventPattern
<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
x => MyList.CollectionChanged += x,
x => MyList.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
.SelectMany(x =>
{
CallMethodWhenAddItem(x);
return x.OnPropertyChange(nameof(x.MyCustomProperty));
})
.Where(x => x.MyCustomProperty == "SomeValue")
.Subscribe(_ => { });
}
public static class Ex
{
public static IObservable<T> OnPropertyChange<T>(this T currentSource, string propertyName)
where T : INotifyPropertyChanged
{
return
Observable
.FromEventPattern
<PropertyChangedEventHandler, PropertyChangedEventArgs>(
eventHandler => eventHandler.Invoke,
x => currentSource.PropertyChanged += x,
x => currentSource.PropertyChanged -= x)
.Where(x => x.EventArgs.PropertyName == propertyName)
.Select(x => currentSource);
}
}
public class MyCustomClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string MyCustomProperty { get; set; }
}
public void CallMethodWhenAddItem(MyCustomClass x) { }
我需要订阅列表中某个对象的 属性。我找到了这个示例 (),它工作得很好,但是如果我向列表中添加一个新元素,它就不起作用。任何解决方案?谢谢!
编辑
IDisposable subscription =
Observable
.FromEventPattern
<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
x => MyList.CollectionChanged += x,
x => MyList.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
.SelectMany(x =>
{
CallMethodWhenAddItem(x);
return x.OnPropertyChange(nameof(x.MyCustomProperty));
})
.Subscribe(x =>
// x is PropertyChangedEventArgs, not MyCustomClass
if (x.MyCustomProperty == "SomeValue") {
RunAction();
}
});
public static IObservable<PropertyChangedEventArgs> OnPropertyChange<T>(this T currentSource, string propertyName)
where T : INotifyPropertyChanged
{
return
Observable
.FromEventPattern
<PropertyChangedEventHandler, PropertyChangedEventArgs>(
eventHandler => eventHandler.Invoke,
x => currentSource.PropertyChanged += x,
x => currentSource.PropertyChanged -= x)
.Where(x => x.EventArgs.PropertyName == propertyName)
.Select(x => x.EventArgs);
}
你能用以下问题指导我吗?
1) 使用"eventHandler => eventHandler.Invoke"和不使用有什么区别。互联网上的许多示例都使用了它,而其他示例则没有。我真的看不出有什么不同。
2) 我如何退订已添加 "dynamically" 的 属性。将其从列表中删除?
谢谢!
System.Func<EventHandler<TEventArgs>, TDelegate>
参数用于将给定的事件处理程序转换为与底层 .NET 事件兼容的委托。如果不需要 - 不要使用它。它实际上用于连接非标准事件处理程序。
您永远不应该进行嵌套订阅。这样你就永远不需要担心处理内部订阅。像这样写您的查询:
IDisposable subscription =
Observable
.FromEventPattern
<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
x => MyList.CollectionChanged += x,
x => MyList.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
.SelectMany(x =>
{
CallMethodWhenAddItem(x);
return x.OnPropertyChange(nameof(x.MyCustomProperty));
})
.Subscribe(_ => { });
根据评论更新:
void Main()
{
var MyList = new ObservableCollection<int>();
IDisposable subscription =
Observable
.FromEventPattern
<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
x => MyList.CollectionChanged += x,
x => MyList.CollectionChanged -= x)
.Where(x => x.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(x => x.EventArgs.NewItems.Cast<MyCustomClass>())
.SelectMany(x =>
{
CallMethodWhenAddItem(x);
return x.OnPropertyChange(nameof(x.MyCustomProperty));
})
.Where(x => x.MyCustomProperty == "SomeValue")
.Subscribe(_ => { });
}
public static class Ex
{
public static IObservable<T> OnPropertyChange<T>(this T currentSource, string propertyName)
where T : INotifyPropertyChanged
{
return
Observable
.FromEventPattern
<PropertyChangedEventHandler, PropertyChangedEventArgs>(
eventHandler => eventHandler.Invoke,
x => currentSource.PropertyChanged += x,
x => currentSource.PropertyChanged -= x)
.Where(x => x.EventArgs.PropertyName == propertyName)
.Select(x => currentSource);
}
}
public class MyCustomClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string MyCustomProperty { get; set; }
}
public void CallMethodWhenAddItem(MyCustomClass x) { }