响应式用户界面应用多个过滤器

时间:2018-09-01 14:53:48

标签: c# reactiveui

我目前正在构建WPF应用程序(我的第一个应用程序),其中一个视图是具有许多列和许多过滤器的DataGrid。

我的问题是过滤,我已经设法通过使用this.WhenAnyValueCreateDerivedCollection方法使其起作用,但是当我添加越来越多的过滤器时,它们彼此独立。

我可以看到我的问题所在,对于每个“过滤器”,我实质上是在覆盖当前过滤器,但是我不确定如何纠正它。

我的想法是,我将不得不将所有过滤器放入this.WhenAnyValue方法中,但是我注意到这限制了12个属性,而且还有很多。

这是初始化ViewModel和过滤器的代码。

public async Task InitializeAsync()
{
    try
    {
        _mortgageTypes = default(MortgageType)
            .ToDictionary()
            .Select(mt => new ComboBoxMortgageType(mt.Key, mt.Value))
            .ToList();

        using (var db = new MortgageDbContext())
        {
            LenderNames =
                await (from l in db.Lenders
                        select new ComboBoxLenderName(l.Id, l.Name)
                    ).ToListAsync();

            LenderNames.Insert(0, new ComboBoxLenderName(Guid.Empty, "None"));

            _rootList = new ReactiveList<LendersView>(await (from l in db.Lenders
                select new LendersView
                {
                    Citizenship = l.Citizenship.GetDescription(),
                    CriteriaUrl = l.CriteriaUrl,
                    Id = l.Id,
                    FirstTimeBuyer = l.FirstTimeBuyer,
                    MaximumAge = l.MaximumAge,
                    MinimumIncome = l.MinimumIncome,
                    Name = l.Name,
                    NewBuilds = l.NewProperty.AcceptBuyToLet || l.NewProperty.AcceptResidential,
                    PrimaryContact = l.PrimaryContactInformation.ToString(),
                    RatesUrl = l.RatesUrl,
                    SecondaryContact = l.SecondaryContactInformation.ToString(),
                    SelfEmployment = l.SelfEmployment.Accept,
                    SelfEmploymentMinimumIncome = l.SelfEmployment.MinimumIncome,
                    SelfEmploymentYearsBooks = l.SelfEmployment.YearsBooks
                }).ToListAsync());
        }

        this.ObservableForProperty(x => x.SelectedLender)
            .Subscribe(_ => { Lenders = _rootList.CreateDerivedCollection(x => x, x => SelectedLender == Guid.Empty || x.Id == SelectedLender); });

        this.WhenAnyValue(x => x.AcceptSelfEmployment, x => x.SelfEmploymentMinimumIncome, x => x.SelfEmploymentYearsBooks)
            .Subscribe(_ =>
            {
                Lenders = _rootList.CreateDerivedCollection(x => x,
                    x => (!AcceptSelfEmployment || x.SelfEmployment == AcceptSelfEmployment) &&
                        (SelfEmploymentMinimumIncome == default || x.SelfEmploymentMinimumIncome >= SelfEmploymentMinimumIncome) &&
                        (SelfEmploymentYearsBooks == default || x.SelfEmploymentYearsBooks >= SelfEmploymentYearsBooks));
            });
    }
    finally
    {
        IsBusy = false;
    }
}

更新

经过Glenns的有帮助的回应,这是我当前拥有的代码。

public SearchViewModel()
{
    IsBusy = true;
    _rootList = new SourceList<LendersView>();

    var lenderFilter = this.WhenValueChanged(x => x.SelectedLender)
        .Select(LenderNamePredicate);

    var loader =_rootList
        .Connect()               
        .Filter(lenderFilter)
        .ObserveOnDispatcher()
        .Bind(out _lenders)
        .Subscribe();
    Task.Run(InitializeAsync).ContinueWith(res => _rootList.AddRange(res.Result));
    _cleanUp = new CompositeDisposable(loader);
}

private Func<LendersView, bool> LenderNamePredicate(Guid selectedLender)
{
    if (selectedLender == Guid.Empty)
    {
        return lender => true;
    }

    return lender => lender.Id == selectedLender;
}

这看起来似乎还不错,但是我正在努力处理这段代码中的复合滤波器

    this.WhenAnyValue(x => x.AcceptSelfEmployment, x => x.SelfEmploymentMinimumIncome, x => x.SelfEmploymentYearsBooks)
        .Subscribe(_ =>
        {
            Lenders = _rootList.CreateDerivedCollection(x => x,
                x => (!AcceptSelfEmployment || x.SelfEmployment == AcceptSelfEmployment) &&
                    (SelfEmploymentMinimumIncome == default || x.SelfEmploymentMinimumIncome >= SelfEmploymentMinimumIncome) &&
                    (SelfEmploymentYearsBooks == default || x.SelfEmploymentYearsBooks >= SelfEmploymentYearsBooks));
        });

动态数据中是否有等同的内容?我是否真的需要每次为每个过滤器添加一个单独的函数?我只是想最终要有大约30-40个滤镜,每个滤镜的功能都会使视图模型更加膨胀。

任何建议都值得赞赏!

0 个答案:

没有答案