Last active
April 14, 2019 15:02
-
-
Save RolandPheasant/3a1bd4cd8c2c7d73ebe43118c5ee18c1 to your computer and use it in GitHub Desktop.
StackOverflow: MergeManyFix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.ObjectModel; | |
using System.Linq; | |
using System.Reactive; | |
using System.Reactive.Linq; | |
using DynamicData.Binding; | |
using FluentAssertions; | |
using ReactiveUI; | |
using Xunit; | |
namespace DynamicData.ReactiveUI.Tests | |
{ | |
public class OriginalExample | |
{ | |
private readonly MainViewModel _mainViewModel; | |
public OriginalExample() | |
{ | |
_mainViewModel = new MainViewModel(); | |
_mainViewModel.OpenDocuments.Add(new DocumentViewModel("1")); | |
_mainViewModel.OpenDocuments.Add(new DocumentViewModel("2")); | |
_mainViewModel.OpenDocuments.Add(new DocumentViewModel("3")); | |
_mainViewModel.OpenDocuments.Add(new DocumentViewModel("4")); | |
} | |
[Fact] | |
public void RunFixedVersion() | |
{ | |
RunTest(true); | |
} | |
[Fact] | |
public void RunBrokenVersion() | |
{ | |
RunTest(false); | |
} | |
private void RunTest(bool useFixedVersion) | |
{ | |
var sut = CreateSut(useFixedVersion); | |
sut.OpenDocuments.Count.Should().Be(4); | |
sut.OpenDocuments.Any(dvm => dvm.Id == "1").Should().BeTrue(); | |
sut.OpenDocuments[0].Close.Execute().Subscribe(); | |
sut.OpenDocuments.Count.Should().Be(3); | |
sut.OpenDocuments.Any(dvm => dvm.Id == "1").Should().BeFalse(); | |
sut.OpenDocuments[0].Close.Execute().Subscribe(); | |
sut.OpenDocuments.Count.Should().Be(2); | |
sut.OpenDocuments.Any(dvm => dvm.Id == "2").Should().BeFalse(); | |
} | |
private MainViewModel CreateSut(bool useFixedVersion) | |
{ | |
var sut = new MainViewModel(useFixedVersion); | |
sut.OpenDocuments.Add(new DocumentViewModel("1")); | |
sut.OpenDocuments.Add(new DocumentViewModel("2")); | |
sut.OpenDocuments.Add(new DocumentViewModel("3")); | |
sut.OpenDocuments.Add(new DocumentViewModel("4")); | |
return sut; | |
} | |
public class MainViewModel : ReactiveObject | |
{ | |
public ObservableCollection<DocumentViewModel> OpenDocuments { get; } | |
public MainViewModel(bool useFix = true) | |
{ | |
OpenDocuments = new ObservableCollection<DocumentViewModel>(); | |
//Fixed version | |
if (useFix) | |
{ | |
//Fixed | |
OpenDocuments | |
.ToObservableChangeSet() | |
.MergeMany(x => x.Close.Select(_ => x)) | |
.Subscribe(x => OpenDocuments.Remove(x)); | |
} | |
else | |
{ | |
//Broken | |
OpenDocuments | |
.ToObservableChangeSet() | |
.AutoRefreshOnObservable(document => document.Close) | |
.Select(_ => WhenAnyDocumentClosed()) | |
.Switch() | |
.Subscribe(x => OpenDocuments.Remove(x)); | |
} | |
} | |
IObservable<DocumentViewModel> WhenAnyDocumentClosed() | |
{ | |
return OpenDocuments | |
.Select(x => x.Close.Select(_ => x)) | |
.Merge(); | |
} | |
} | |
public class DocumentViewModel : ReactiveObject | |
{ | |
public string Id { get; } | |
public ReactiveCommand<Unit, Unit> Close { get; } | |
public DocumentViewModel(string id) | |
{ | |
Id = id; | |
// Note that we don't actually *subscribe* to Close here or implement | |
// anything in DocumentViewModel, because Closing is a responsibility | |
// of the document list. | |
Close = ReactiveCommand.Create(() => { }); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment