Observable.FromEvent 可以与 DataContextChanged 一起使用吗

发布于 2024-12-03 23:01:42 字数 469 浏览 1 评论 0原文

我想获取控件的 DataContext 作为 IObservable。我已经尝试过这个:

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

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

我的猜测是,这是因为 DependencyPropertyChangedEventArgs 不继承自事件参数,但我不确定。任何有关正确方法的建议将不胜感激。

I want to get the DataContext of a control as an IObservable. I've tried this:

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

Which compiles fine, but at the point where Subscribe is called it throws the exception: Error binding to target method.

My guess is that this is because DependencyPropertyChangedEventArgs doesn't inherit from event args, but I'm not sure. Any advice on the right way to do this would be apreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

疏忽 2024-12-10 23:01:42

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()));

这似乎有效

One of the other overloads for FromEvent allows you to create the delegate yourself from a method. Allowing you to do this:

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()));

which seems to work

活雷疯 2024-12-10 23:01:42

您已经“击中要害”了,由于某种原因 DependencyPropertyChangedEventArgs 是一个结构,因此不会继承 EventArgs。请参阅此相关博客文章:

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

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

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

You have 'hit the nail on the head', for some reason DependencyPropertyChangedEventArgs is a struct, and hence does not inherit EventArgs. See this related blog post:

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

This makes it impossible to handle this event using a generic event handling mechanism.

I guess you will have to handle this event in your own code and create an Observable manually.

紫﹏色ふ单纯 2024-12-10 23:01:42

自定义实现将非常简单:

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));
                });
            });
        }

The custom implementation would be as simple as:

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);
});

UPDATED : To handle event handler removal

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));
                });
            });
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文