Как обрабатывать производные списки с использованием Reactive Extensions - PullRequest
0 голосов
/ 17 апреля 2020

Учитывая простой элемент с возможностью мягкого удаления

public class Person : ReactiveObject
{
    [Reactive] public string Name { get; set; }
    [Reactive] public bool IsDeleted { get; set; }
}

Мне нужно обработать удаленные обновления и удалить элементы в пользовательском интерфейсе (сохраняя их в списке).

Когда Я пытаюсь это сделать: удаленный элемент не отфильтровывается из производного списка.

public class PeopleViewModel : ReactiveObject
{
    public PeopleViewModel()
    {
        DeleteCommand = ReactiveCommand.Create(DeletePerson);
        this.WhenAnyValue(vm => vm.People)
            .Subscribe(people => people
                .ToObservableChangeSet()
                .Filter(x => !x.IsDeleted)
                .ToCollection()
                .Select(x => new ObservableCollection<Person>(x))
                .ToPropertyEx(this, x => x.VisiblePerson));
    }

    private void DeletePerson(Person person)
    {
        person.IsDeleted = true;
    }

    ICommand DeleteCommand { get; }
    [Reactive] public ObservableCollection<Person> People { get; set;}
    public ObservableCollection<Person> VisiblePeople { [ObservableAsProperty] get;}
}

Как правильно создать производный список, при котором при изменении свойства в списке запускается ObservableChangeSet для обновления ?

------------------------------------------
|  John Smith                   [delete] |
------------------------------------------
|  Jane Doe                     [delete] |
------------------------------------------

Редактировать

Я справился со следующим, но это действительно грязно

this.WhenAnyValue(vm => vm.People)
            .Subscribe(people => people
                .ToObservableChangeSet()
                .AsObservableList()
                .Connect()
                .WhenPropertyChanged(x => x.Deleted)
                .Subscribe(_ => people
                    .ToObservableChangeSet()
                    .Filter(x => !x.Deleted)
                    .ToCollection()
                    .Select(x => x.ToList().AsReadOnly())
                    .DistinctUntilChanged()
                    .ToPropertyEx(this, x => x.VisiblePeople))

1 Ответ

0 голосов
/ 17 апреля 2020

Так что я был одержим тем фактом, что .Bind(out) не уведомлял пользовательский интерфейс об изменениях. Оказывается, это правильный подход, который делает все необходимое для производных списков.

ctor()
{
    this.WhenAnyValue(vm => vm.People)
        .Subscribe(people => people
            .ToObservableChangeSet()
            .AutoRefresh(x => x.Deleted)
            .Filter(x => !x.Deleted)
            .Bind(out _visiblePeople)
            .Subscribe());
}

private ReadOnlyObservableCollection<Person> _visiblePeople;
public ReadOnlyObservableCollection<Person> VisiblePeople => _visiblePeople;
...