ReactiveUI:对属性的变化做出反应

本文关键字:变化 属性 ReactiveUI | 更新日期: 2023-09-27 18:03:18

我正在用ReactiveUI做我的第一步,但我不能得到一个非常基本的例子来工作。我想执行一个任务,只要属性"SearchTerm"的变化。我按照ReactiveUI的github页面上的说明("一个引人注目的例子")。

我有一个ViewModel的属性SearchTerm是绑定到一个文本框在我的视图。如果我更新TextBox的内容,属性将按照预期更新(我使用UpdateSourceTrigger=PropertyChanged)。

我的可观察对象中的代码永远不会触发:

public class MainWindowViewModel: ReactiveObject
{
    public string SearchTerm
    {
         get { return m_SearchTerm; }
         set { this.RaiseAndSetIfChanged(ref m_SearchTerm, value); }
    }
    private string m_SearchTerm;
    public MainWindowViewModel()
    {
        SearchResults = new List<string>();
        var canSearch = this.WhenAny(x => x.SearchTerm, x => !string.IsNullOrWhiteSpace(x.GetValue()));
         var search = ReactiveCommand.CreateAsyncTask(canSearch,
                async _ => {
                    // this is never called
                    return await dosearch(this.SearchTerm);
                });
            search.Subscribe(results => {
                // this is never called too
                SearchResults.Clear();
                SearchResults.AddRange(results);
            });
        }
        private async Task<List<string>> dosearch(string searchTerm)
        {
            await Task.Delay(1000);
            return new List<string>() { "1", "2", "3" };
        }
        public List<string> SearchResults { get; private set; }
    }

ReactiveUI:对属性的变化做出反应

命令中的代码永远不会触发,因为您没有在任何地方调用该命令。您必须将命令绑定到任何事件(如输入文本更改,按钮单击等)。

首先,从ViewModel公开命令:

public ReactiveCommand<List<string>> Search { get; private set; }

接下来,在构造函数中赋值:

this.Search = ReactiveCommand.CreateAsyncTask(canSearch,
                async _ => {
                    return await dosearch(this.SearchTerm);
                });

,最后,在输入改变时调用命令(这是代码中缺失的关键部分):

this.WhenAnyValue(x => x.SearchTerm)
    .InvokeCommand(this, x => x.Search);

把上面的代码放到构造函数中。

注意,这将在用户键入时不断触发搜索。要解决这个问题,您可以使用名为Throttle的Rx操作符,如您链接到的示例所示。