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



我以前从未使用过ReactiveExtensions。我在网上查找,但找不到适合我需求的方法。与我需要实现的目标相比,所有示例似乎都有点"过头"。

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

目前我有以下内容:

private string _searchText;
public String SearchText
{
  get { return _searchText; }
  set
  {
    _searchText = value;
    MyMethod();   
  }
}
<textbox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"/>

除了在支持字段上设置值并引发更改通知外,您的属性不应执行其他操作所有其他逻辑都应该放在外面,通过可观察量监听这些更改通知。

在您的情况下,您希望仅在经过一定时间后侦听通知,因此您可以使用 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;

第一个解决方案:视图模型中的限制:

// 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()方法中......

第二种解决方案:使用绑定的 Delay 属性

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

它有相同的结果。

相关内容

  • 没有找到相关文章

最新更新