WPF 中 .NET (Rx) 的反应式扩展 - MVVM

发布于 2024-10-10 10:25:33 字数 2234 浏览 0 评论 0原文

我在我的 WPF 应用程序中使用 NET (Rx) 的响应式扩展和 Caliburn.Micro。我正在尝试移植我的 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。像这样的

WPF 与 MVVM

View:

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

View Model:

[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 控件的某些事件,但此方法使用视图中的对象。

感谢您的想法。

I am using Reactive extensions for NET (Rx) with Caliburn.Micro in my WPF app. I'm trying to port my WPF app to use an MVVM architecture and I need to monitor changes in the Text property of a TextBox control.

If the last change of the Text property was more than 3 seconds ago I need to call the LoadUser method of a service.

Porting the logic from my old solution to the new solution with MVVM architecture.

OLD

XAML:

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

In code behind I have this:

...

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){...}

I would like use Observable.FromEvent in my view model class. Something like this

WPF with MVVM

View:

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

View Model:

[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()
    {
    }
}

My problem is Observable.FromEvent uses the TextBox control and I don’t know how can I access this control from my ViewModel class.

I can bind to the Text property of TextBox or I can bind a command to some event of the TextBox control, but this method uses an object in the View.

Thank for ideas.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秋千易 2024-10-17 10:25:33

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}" />

Add a Nick property to your ViewModel and implement INotifyPropertyChanged. Then you can do this

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);  

and then your XAML would be something like this

<TextBox Name="Nick" 
         Grid.Row="0"
         FontSize="14"
         Margin="2,2,2,2" 
         HorizontalAlignment="Stretch"
         Text="{Binding Nick, UpdateSourceTrigger=PropertyChanged}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文