Observable.FromEvent是否可以与DataContextChanged一起使用

3

我希望能够将控件的DataContext作为IObservable获取。我已经尝试了以下方法:

Observable.FromEvent<DependencyPropertyChangedEventHandler,
     DependencyPropertyChangedEventArgs>
     (a => this.DataContextChanged += a, a => this.DataContextChanged -= a)
     .Subscribe(e => MessageBox.Show(e.NewValue.ToString()));

编译没有问题,但在调用“Subscribe”时会抛出异常:“绑定到目标方法的错误”。我猜这是因为DependencyPropertyChangedEventArgs没有继承自事件参数,但我不确定。如果您有任何关于正确方法的建议,将不胜感激。
3个回答

5

FromEvent 的其他重载之一允许您自己从方法创建委托。这使您可以执行以下操作:

Observable.FromEvent
    <DependencyPropertyChangedEventHandler, DependencyPropertyChangedEventArgs>
    (a => new DependencyPropertyChangedEventHandler(
        new Action<object, DependencyPropertyChangedEventArgs>((s, e) => a(e))),
        h => this.DataContextChanged += h, h => this.DataContextChanged -= h)
        .Subscribe(e => MessageBox.Show(e.NewValue.ToString()));

看起来是有效的。


1
@Tuskan460 - 你可以将 a => new DependencyPropertyChangedEventHandler(new Action<object, DependencyPropertyChangedEventArgs>((s, e) => a(e))) 简化为 a => (s, e) => a(s, e) - Enigmativity

1

你说得一点也没错,DependencyPropertyChangedEventArgs 是一个结构体,因此没有继承 EventArgs。请参考这篇相关的博客文章:

http://weblogs.asp.net/okloeten/archive/2007/12/10/5430331.aspx

这使得使用通用事件处理机制无法处理此事件。
我想你将不得不在自己的代码中处理此事件并手动创建一个“Observable”。

0

自定义实现将非常简单:

Observable.CreateWithDisposable<DependencyPropertyChangedEventHandler>(obs =>
{
   var subject = new Subject<DependencyPropertyChangedEventHandler>();
   //Attach event handler and on event call OnNext of subject with the value
   return subject.Subscribe(obs);
});

更新:为了处理事件处理程序的移除

public class GenericDisposable : IDisposable
        {
            Action _act = null;
            IDisposable _disp = null;
            public GenericDisposable(Action act,IDisposable disp)
            {
                _act = act;
                _disp = disp;
            }
            public void Dispose()
            {
                _act();
                _disp.Dispose();
            }
        }
        public static IObservable<DependencyPropertyChangedEventHandler> CreateForEvent()
        {
            return Observable.Defer(() =>
            {
                return Observable.CreateWithDisposable<DependencyPropertyChangedEventHandler>(obs =>
                {
                    var subject = new Subject<DependencyPropertyChangedEventHandler>();
                    //Attach event handler and on event call OnNext of subject with the value
                    return new GenericDisposable(() => {/*remove event handler*/}, subject.Subscribe(obs));
                });
            });
        }

这不会分离事件处理程序,即使您取消了对可观察对象的订阅。 - ForbesLindesay
是的,但通常不需要这样做。虽然你可以采用复杂的方式来处理所有这些边缘情况。 - Ankur
通常情况下,这并不是必需的要求,我现在也不需要它,只是觉得在更普遍地解决问题时拥有它会很好。 - ForbesLindesay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接