2

我只是在阅读 Rx HOL NET。找到后(示例使用 Windows 窗体):

var moves = Observable.FromEvent<MouseEventArgs>(frm, "MouseMove");

我想知道如何在某些 WPF MVVM 设置中实例化并将移动的引用传递给 ViewModel?据我了解,尝试在 ViewModel 中过滤此数据流确实很有意义。

或者,如何为 TextBox 的键盘输入做类似的事情?例如,在这种情况下,您不会将某些文本屏蔽行为附加到 XAML 中的控件,而是让 VM 中的 Observer 过滤和验证键盘输入。

我完全偏离轨道了吗?

4

3 回答 3

5

这是一个如何MVVM 方式实现 Web 服务字典的示例。它分为三个部分:

  1. ObservablePropertyBacking 类,支持(T 的)属性,也实现了 IObservable
  2. MyViewModel 类。它包含一个使用 ObservablePropertyBacking 作为后备存储的 CurrentText 属性。它还观察此属性的值并使用它来调用字典 Web 服务。
  3. MainView.xaml 包含一个文本框。它的 Text 属性双向绑定到视图模型上的 CurrentText 属性。

MyViewModel.cs:

class MyViewModel: INotifyPropertyChanged
{
    #region INotifyPropertyChanged implementation

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string p)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(p));
    }

    #endregion

    public MyViewModel()
    {
        SetupProperties();
    }

    #region CurrentText

    /*  We use a special class for backing of the CurrentText property. This object
     *  holds the value of the property and also dispatches each change in an observable 
     *  sequence, i.e. it implements IObservable<T>.
     */
    private ObservablePropertyBacking<string> _textInput;
    public string CurrentText
    {
        get { return _textInput.Value; }
        set
        {
            if (value == _textInput.Value) { return; }
            _textInput.Value = value;
            RaisePropertyChanged("CurrentText");
        }
    }

    #endregion

    /*  Create property backing storage and subscribe UpdateDictionary to the observable 
        *  sequence. Since UpdateDictionary calls a web service, we throttle the sequence.
        */
    private void SetupProperties()
    {
        _textInput = new ObservablePropertyBacking<string>();
        _textInput.Throttle(TimeSpan.FromSeconds(1)).Subscribe(UpdateDictionary);
    }

    private void UpdateDictionary(string text)
    {
        Debug.WriteLine(text);
    }
}

ObservablePropertyBacking.cs:

public class ObservablePropertyBacking<T> : IObservable<T>
{
    private Subject<T> _innerObservable = new Subject<T>();

    private T _value;
    public T Value
    {
        get { return _value; }
        set
        {
            _value = value;
            _innerObservable.OnNext(value);
        }
    }

    public IDisposable Subscribe(IObserver<T> observer)
    {
        return _innerObservable
            .DistinctUntilChanged()
            .AsObservable()
            .Subscribe(observer);
    }
}

MainPage.xaml:

  <Window 
    x:Class="RxMvvm_3435956.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
      <TextBox
        Text="{Binding CurrentText, UpdateSourceTrigger=PropertyChanged}" />
    </Grid>
  </Window>
于 2010-08-10T20:15:43.887 回答
1

进行键盘示例的最简单方法是将文本双向绑定到 ViewModel 的属性。然后,Text setter 可以写入Subject您的其余代码用作IObservable<string>. 从那里,您可以完成 HOL 示例。

鼠标移动通常被认为太“视图”而不能放入 ViewModel,但如果产生的逻辑足够复杂,您可以让它执行ICommand或将逻辑放入行为中。如果它ICommand您可以让命令具有WhenExecuted IObservable可以在 ViewModel 中获取的属性。`

于 2010-08-09T06:39:03.827 回答
1

这可能会有所帮助:反应式扩展 (Rx) + MVVM = ?

于 2010-08-08T21:36:58.903 回答