如何解开嵌套的IObservable或IObservable >

问题描述 投票:0回答:1

我正在尝试从以下代码创建IObservable<string>,但是我似乎找不到找到正确解开事件处理程序值的方法。

发生的事情是,PasswordBox可能会更改,因此,每当我想要观察它时,都将在其上进行观察,并在引发密码更改事件时提供一个字符串资源。如果我对普通事件进行处理,效果很好,但我对使用System.Reactive如何工作感到好奇。

        var passwordChanged = WhenPropertyChanged
            .Where(name => nameof(PasswordBox) == name)
            .Select(d => PasswordBox)
            .Where(d => d != null)
            .Select(box =>
            {
                return Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>(
                    handler => box.PasswordChanged += handler,
                    handler => box.PasswordChanged -= handler);
            }).Select(d => nameof(Password));

对我来说,似乎必须在Select(box => ...部分内有某种方式,我可以返回一个可以用于正确订阅的对象(IObservable<IObservable<RoutedEventArgs>>除外)。

像下面的作品那样做。但是我认为,如果您端到端使用它,那么React可以更好地避免事件处理程序内存泄漏。

        var passwordHasChanged = new Subject<string>();
        // listen for changes of the password
        WhenPropertyChanged
            .Where(name => nameof(PasswordBox) == name)
            .Select(d => PasswordBox)
            .Where(d => d != null)
            .Subscribe(box =>
            {
                box.PasswordChanged += (sender, args) => passwordHasChanged.OnNext(nameof(Password));
            });

        passwordHasChanged.Subscribe(d => Log.Debug("Password changed"));
c# system.reactive
1个回答
2
投票
如果只希望从最后一次输入密码中获取事件,请使用Switch

[Switch适用于IObservable<IObservable<T>>,并且在获得较新的观测值时取消订阅先前的观测值。

var passwordChanged = WhenPropertyChanged .Where(name => nameof(PasswordBox) == name) .Select(d => PasswordBox) .Where(d => d != null) .Select(box => Observable.FromEvent<RoutedEventHandler, RoutedEventArgs>( handler => box.PasswordChanged += handler, handler => box.PasswordChanged -= handler); ) .Switch() .Select(d => nameof(Password));

© www.soinside.com 2019 - 2024. All rights reserved.