Observable.FromEvent可以与DataContextChanged一起使用

时间:2011-09-08 10:37:26

标签: c# wpf system.reactive

我想将控件的DataContext作为IObservable。我试过这个:

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

编译很好,但在调用Subscribe的时候会抛出异常:绑定到目标方法的错误。

我的猜测是因为DependencyPropertyChangedEventArgs不会从事件args继承,但我不确定。任何关于正确方法的建议都是不可取的。

3 个答案:

答案 0 :(得分: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 :(得分:1)

由于某种原因,{'1}}是一个结构,因此你没有'{1}}继承。请参阅此相关博文:

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

这使得无法使用通用事件处理机制处理此事件。

我想您必须在自己的代码中处理此事件并手动创建DependencyPropertyChangedEventArgs

答案 2 :(得分: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));
                });
            });
        }