12

我在我的 WPF 应用程序中使用带有 Caliburn.Micro 的 NET (Rx) 响应式扩展。我正在尝试移植我的 WPF 应用程序以使用 MVVM 架构,并且我需要监视 TextBox 控件的 Text 属性的更改。

如果 Text 属性的最后一次更改是在 3 秒之前,我需要调用服务的 LoadUser 方法。

使用 MVVM 架构将逻辑从我的旧解决方案移植到新解决方案。

老的

XAML:

<TextBox Name="Nick" 
         Grid.Row="0"
         FontSize="14"
         Margin="2,2,2,2" 
         HorizontalAlignment="Stretch" 
         TextChanged="Nick_TextChanged" />

后面的代码中我有这个:

...

Observable.FromEvent<TextChangedEventArgs>(Nick, "TextChanged")
          .Select(e => ((TextBox)e.Sender).Text)
          .Where(text => text.Length > 3)               
          .Do(LoadUser)     
          .Throttle(TimeSpan.FromSeconds(3000))     
          .Subscribe(LoadUser);

...
private  void LoadUser(string text){...}

我想在我的视图模型类中使用 Observable.FromEvent 。像这样的东西

带有 MVVM 的 WPF

看法:

<TextBox Name="Nick" 
         Grid.Row="0"
         FontSize="14"
         Margin="2,2,2,2" 
         HorizontalAlignment="Stretch"
         Micro:Message.Attach="[TextChanged]=[Action TextChanged()]"/>

查看型号:

[Export(typeof(IAddFriendViewModel))]
public class AddFriendViewModel : Screen, IAddFriendViewModel
{
    private string _nick;

    public string Nick
    {
        get { return _nick; }
        set
        {
            _nick = value;
            NotifyOfPropertyChange(()=>Nick);
        }
    }

    ...

    //how can I access to textbox control Nick in view from view model class?
    Observable.FromEvent<TextChangedEventArgs>(Nick, "TextChanged")
              .Select(e => ((TextBox)e.Sender).Text)
              .Where(text => text.Length > 3)
              .Do(LoadUser)
              .Throttle(TimeSpan.FromSeconds(3000))
              .Subscribe(LoadUser);
    ...

    private void LoadUser(string text)
    { }

    public void TextChanged()
    {
    }
}

我的问题是 Observable.FromEvent 使用 TextBox 控件,我不知道如何从 ViewModel 类访问该控件。

我可以绑定到 TextBox 的 Text 属性,也可以将命令绑定到 TextBox 控件的某个事件,但此方法使用视图中的对象。

感谢您的想法。

4

1 回答 1

25

Nick属性添加到您的 ViewModel 并实现INotifyPropertyChanged. 然后你可以这样做

Observable.FromEventPattern<PropertyChangedEventArgs>(this, "PropertyChanged")
          .Where(e => e.EventArgs.PropertyName == "Nick")
          .Select(_ => this.Nick)
          .Where(text => text.Length > 3)
          //Subscribe will call LoadUser, no need for the extra Do(...)
          .Throttle(TimeSpan.FromSeconds(3000))
          .Subscribe(LoadUser);  

然后你的 XAML 会是这样的

<TextBox Name="Nick" 
         Grid.Row="0"
         FontSize="14"
         Margin="2,2,2,2" 
         HorizontalAlignment="Stretch"
         Text="{Binding Nick, UpdateSourceTrigger=PropertyChanged}" />
于 2011-01-03T15:53:17.577 回答