Как получить поток событий Rx Observable внутри MVVM ViewModel - PullRequest
2 голосов
/ 09 августа 2010

Я просто читал Rx HOL NET. После нахождения (пример использует Windows Forms):

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

Интересно, как я могу создать экземпляр и передать ссылку на перемещения в ViewModel в некоторых настройках WPF MVVM? В моем понимании имеет смысл попытаться отфильтровать этот поток данных внутри ViewModel.

Или как сделать что-то подобное для ввода с клавиатуры в TextBox? В этом сценарии вы, например, не добавили бы некоторые маскирующие свойства текста к элементу управления в XAML, но вместо этого позволили бы Observer в VM фильтровать и проверять ввод с клавиатуры.

Я полностью сошел с трассы?

Ответы [ 3 ]

5 голосов
/ 11 августа 2010

Вот пример того, как вы могли бы реализовать словарь веб-службы в стиле MVVM.Он состоит из трех частей:

  1. Класс ObservablePropertyBacking, поддержка свойств (T), который также реализует IObservable
  2. Класс MyViewModel.Он содержит свойство CurrentText, которое использует ObservablePropertyBacking в качестве резервного хранилища.Он также наблюдает за значением этого свойства и использует его для вызова веб-службы словаря.
  3. MainView.xaml, который содержит TextBox.Его свойство 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>
1 голос
/ 09 августа 2010

Самый простой способ сделать пример клавиатуры - это двустороннее связывание текста со свойством ViewModel. Затем установщик текста может записать в приватное Subject, что остальная часть вашего кода использует в качестве основы IObservable<string>. Оттуда вы можете заполнить образец HOL.

Движения мыши, как правило, считаются слишком «представлением», чтобы помещать их в ViewModel, но если полученная логика была достаточно сложной, вы могли бы заставить ее выполнить ICommand или, возможно, поместить логику в поведение. Если бы это было и ICommand, вы могли бы иметь команду, имеющую свойство WhenExecuted IObservable, которое вы могли бы получить в своей ViewModel.

1 голос
/ 09 августа 2010
...