【问题标题】:How to get Rx Observable event stream inside MVVM ViewModel如何在 MVVM ViewModel 中获取 Rx Observable 事件流
【发布时间】:2010-08-08 20:29:06
【问题描述】:

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

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

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

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

我完全偏离轨道了吗?

【问题讨论】:

    标签: mvvm system.reactive observable


    【解决方案1】:

    这是一个示例,说明您如何以 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>
    

    【讨论】:

      【解决方案2】:

      这可能会有所帮助:Reactive Extensions (Rx) + MVVM = ?

      【讨论】:

      • 我发现这确实很有用,但我仍在努力了解如何以 MVVM 方式使用 Web 服务字典准确实现 HOL 示例。
      【解决方案3】:

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

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

      【讨论】:

      • 我真的很想在周围的博客中看到更完整的示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 2011-03-13
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多