Может ли Observable.FromEvent использоваться с DataContextChanged - PullRequest
3 голосов
/ 08 сентября 2011

Я хочу получить 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 голосов
/ 08 сентября 2011

Одна из других перегрузок для 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 голос
/ 08 сентября 2011

Вы «ударили ноготь по голове», по какой-то причине DependencyPropertyChangedEventArgs является структурой и, следовательно, не наследует EventArgs. Смотрите это сообщение в блоге:

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

Это делает невозможным обработку этого события с использованием общего механизма обработки событий.

Полагаю, вам придется обработать это событие в своем собственном коде и вручную создать Observable.

0 голосов
/ 08 сентября 2011

Пользовательская реализация будет проста:

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