对属性调用的方法的反应式扩展

时间:2017-05-16 08:51:01

标签: c# wpf system.reactive

之前我从未使用过ReactiveExtensions。我在网上看了,真的找不到符合我需求的方法。所有的例子似乎有点过头了#34;与我需要达到的目标相比。

我有一个方法可以为我做所有事情,所以我不需要返回值然后设置我的列表。我想要的是在用户最终停止输入时执行该方法,而不是在用户输入时执行。如何通过使用反应式扩展来实现这一目标。

目前我有以下内容:

 "main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
  "scripts": {
    "start": "react-native-scripts start",
    "eject": "react-native-scripts eject",
    "android": "react-native-scripts android",
    "ios": "react-native-scripts ios",
    "test": "node node_modules/jest/bin/jest.js --watch",
    "menu": "adb shell input keyevent 82"
  },

1 个答案:

答案 0 :(得分:0)

除了在后备字段中设置值并提出更改通知外,您的属性不会发生。 其他逻辑应放在外面,通过以下方式收听这些更改通知一个观察者。

在您的情况下,您希望仅在经过一定时间后才收听通知,因此您可以使用IObservable.Throttle运算符在转发通知之前等待一段时间。

因此,这可以是INotifyPropertyChanged的简单实现:

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

这就是你应该写每个属性的方法:

// Just check if value is different from the actual backing field.
// If and only if it is, set the backing field and raise the PropertyChanged event.
public string SearchText
{
    get { return _SearchText; }
    set
    {
        if (!EqualityComparer<string>.Default.Equals(_SearchText, value))
        {
            _SearchText = value;
            NotifyPropertyChanged();
        }
    }
}
private string _SearchText;

第一个解决方案:ViewModel中的节流:

// Transform the PropertyChanged event in an Observable
var changed = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
    h => PropertyChanged += h,
    h => PropertyChanged -= h);

// Transform the Observable to your need,
// filtering only when SearchText changes
changed.Where(x => x.EventArgs.PropertyName == nameof(SearchText))
// Wait 500 ms before forwarding the notification;
// if another char in inserted from the user beside this interval,
// the previous value is ignored
.Throttle(TimeSpan.FromMilliseconds(500))
// Necessary to avoid cross-thread Exceptions
.ObserveOn(Scheduler.CurrentThread)
// finally, subscribe your method:
.Subscribe(_ => MyMethod());

您可以将以上代码放在任何合适的位置:在ViewModel的构造函数中,使用Init()方法...

第二个解决方案:使用Bindings的Delay属性

Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged, Delay=500}"

它有相同的结果。