用户在

时间:2019-02-13 11:40:31

标签: c# reactive-programming reactiveui

我在ReactiveList<string>中有一个字符串根目录

private ReactiveList<string> Items { get; set; }

和派生列表

private IReactiveDerivedList<string> _FilteredItems;
public IReactiveDerivedList<string> FilteredItems{ get => _FilteredItems; set => this.RaiseAndSetIfChanged(ref _FilteredItems, value); }

我还有一个过滤条件,它会随着用户输入TextBox

而变化
private string _FilterTerm;
public string FilterTerm { get => _FilterTerm; set => this.RaiseAndSetIfChanged(ref _FilterTerm, value); }

最后,我在构造函数中使用以下代码,每次FilterTerm更改时,该函数都会重新创建列表

this.WhenAnyValue(This => This.FilterTerm).Where(filterTerm => filterTerm != null).Subscribe((filterTerm) =>
{
    FilteredItems = Items.CreateDerivedCollection(x => x, x => x.Contains(FilterTerm));
});

...我是否正确执行此操作,还是有更好的方法,因为这有点像“我每次都只能创建一个新的ReactiveList,为什么要麻烦IReactiveDerivedList”?


更新

我找到了下面的示例,https://janhannemann.wordpress.com/2016/10/18/reactiveui-goodies-ireactivederivedlist-filtering-2/几乎对我有用,但是它要求我向ViewModel中添加一个IsFiltered属性,但是在这种情况下,我没有使用一个ViewModel,我只是在使用string

1 个答案:

答案 0 :(得分:2)

如我的评论中所述。 ReactiveUI框架不赞成使用ReactiveList,而推荐使用DynamicData https://reactiveui.net/docs/handbook/collections/

如果要在DynamicData中实现此目标,请执行以下操作:

using System.Collections.ObjectModel;
using DynamicData;

public class FilteringClass
{
   private readonly ReadOnlyObservableCollection<string> _filteredItems;
   private readonly SourceList<string> _items = new SourceList<string>();
   private string _filterTerm;

   public FilteringClass(IEnumerable<string> items)
   {
      var filterTermChanged = this.WhenAnyValue(x => x.FilterTerm);
      _items.AddRange(items);
      _items.Connect()
         // This will update your output list whenever FilterTerm changes.
         .AutoRefreshOnObservable(_ => filterTermChanged)
         // This is similar to a Where() statement.
         .Filter(x => FilterTerm == null || x.Contains(FilterTerm))
         // SourceList is thread safe, this will make your output list only be updated on the main thread.
         .ObserveOn(RxApp.MainThreadScheduler)
         // This will make the FilteredItem's be updated with our data.
         .Bind(out _filteredItems)
         // This is a observable, so Subscribe to start the goodness.
         .Subscribe();

   }

   public string FilterTerm
   {
      get => _filterTerm;
      set => RaiseAndSetIfChanged(ref _filterTerm, value);
   }

   public ReadOnlyObservableCollection<string> FilteredItems => _filteredItems;
}