public MainWindowViewModel(IOccupationParser occupationParser) { this._occupationParser = occupationParser; var occupationTypesSourceList = new SourceList <OccupationType>(); var occupationsSourceList = new SourceList <Occupation>(); var occupationTypes = occupationTypesSourceList.Connect().Transform(x => new CheckedItemViewModel(x.GetDescription(), true)).Publish(); var occupations = occupationsSourceList.Connect().Transform(x => new OccupationViewModel(x)).Publish(); IObservable <Func <OccupationViewModel, bool> > filter = occupationTypes.AutoRefresh(x => x.IsChecked).Filter(x => x.IsChecked).Transform(x => x.Name) .ToCollection() .Throttle(TimeSpan.FromMilliseconds(250)) .Select(items => { var types = items.Select(t => t.GetValueFromDescription <OccupationType>()); OccupationType?type = null; foreach (var item in types) { if (type == null) { type = item; } else { type |= item; } } bool Predicate(OccupationViewModel vm) => type.HasValue && type.Value.HasFlag(vm.OccupationType); return((Func <OccupationViewModel, bool>)Predicate); }); occupationTypes.AutoRefresh(x => x.IsChecked).Filter(x => x.IsChecked).Throttle(TimeSpan.FromMilliseconds(350)).ObserveOn(RxApp.MainThreadScheduler).Subscribe(x => { for (int i = 0; i < Occupations.Count; i++) { Occupations[i].SerialNumber = i + 1; } }); occupationTypes.ObserveOn(RxApp.MainThreadScheduler).Bind(out this._occupationTypes).Subscribe(); occupations.Filter(filter).ObserveOn(RxApp.MainThreadScheduler).Bind(out this._occupations).Subscribe(); occupationTypes.Connect(); occupations.Connect(); Initialize = ReactiveCommand.CreateFromTask(async() => { var result = await this._occupationParser.ParseDataAsync("Occupations.txt"); occupationsSourceList.AddRange(result); occupationTypesSourceList.AddRange(Enum.GetValues(typeof(OccupationType)).Cast <OccupationType>()); }); GetItemWithSerialNumber = ReactiveCommand.Create <int>(number => { SelectedItem = Occupations.SingleOrDefault(x => x.SerialNumber == number); }); Random = ReactiveCommand.CreateFromTask(async() => { var random = new Random(); var number = random.Next(1, Occupations.Count); await GetItemWithSerialNumber.Execute(number); }); }