Created
June 19, 2015 05:52
-
-
Save runceel/385d80e7ae4caaf9015f to your computer and use it in GitHub Desktop.
This file contains 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 Reactive.Bindings; | |
using System; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
namespace WpfApplication11 | |
{ | |
public class MainWindowViewModel | |
{ | |
private readonly ObservableCollection<Person> people = new ObservableCollection<Person>(); | |
public ReadOnlyReactiveCollection<PersonViewModel> People { get; private set; } | |
public ReactiveCommand AddCommand { get; private set; } | |
private DuplicateManager duplicateManager = new DuplicateManager(); | |
public MainWindowViewModel() | |
{ | |
this.People = people.ToReadOnlyReactiveCollection(x => | |
{ | |
var vm = new PersonViewModel(x); | |
vm.Disposed += this.VM_Disposed; | |
this.duplicateManager.Added(vm); | |
vm.Name.Subscribe(_ => this.NameChanged(vm)); | |
return vm; | |
}); | |
this.AddCommand = new ReactiveCommand(); | |
this.AddCommand.Subscribe(_ => this.people.Add(new Person { Name = "okazuki" })); | |
var collectionChanged = this.people | |
.ToCollectionChanged(); | |
} | |
private void NameChanged(PersonViewModel vm) | |
{ | |
this.duplicateManager.Changed(vm); | |
} | |
private void VM_Disposed(object sender, EventArgs e) | |
{ | |
var vm = (PersonViewModel)sender; | |
this.duplicateManager.Removed(vm); | |
vm.Disposed -= this.VM_Disposed; | |
} | |
} | |
class DuplicateManager | |
{ | |
private readonly Dictionary<string, List<PersonViewModel>> map = new Dictionary<string, List<PersonViewModel>>(); | |
private readonly Dictionary<PersonViewModel, string> reverseMap = new Dictionary<PersonViewModel, string>(); | |
public void Added(PersonViewModel vm) | |
{ | |
this.reverseMap[vm] = vm.Name.Value; | |
var list = this.GetMapList(vm.Name.Value); | |
list.Add(vm); | |
this.ApplyBackgroundColor(list); | |
} | |
public void Changed(PersonViewModel vm) | |
{ | |
this.Removed(vm); | |
this.Added(vm); | |
} | |
public void Removed(PersonViewModel vm) | |
{ | |
var oldName = this.reverseMap[vm]; | |
var list = this.GetMapList(oldName); | |
list.Remove(vm); | |
this.reverseMap.Remove(vm); | |
this.ApplyBackgroundColor(list); | |
} | |
private List<PersonViewModel> GetMapList(string p) | |
{ | |
if (this.map.ContainsKey(p)) | |
{ | |
return this.map[p]; | |
} | |
var list = new List<PersonViewModel>(); | |
map[p] = list; | |
return list; | |
} | |
private void ApplyBackgroundColor(List<PersonViewModel> l) | |
{ | |
var color = l.Count > 1 ? "Red" : "White"; | |
foreach (var item in l) { item.BackgroundColor.Value = color; } | |
} | |
} | |
} |
This file contains 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.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace WpfApplication11 | |
{ | |
public class Person : BindableBase | |
{ | |
private string name; | |
public string Name | |
{ | |
get { return this.name; } | |
set { this.SetProperty(ref this.name, value); } | |
} | |
} | |
} |
This file contains 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 Reactive.Bindings; | |
using Reactive.Bindings.Extensions; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reactive.Disposables; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace WpfApplication11 | |
{ | |
public class PersonViewModel : IDisposable | |
{ | |
private readonly CompositeDisposable disposable = new CompositeDisposable(); | |
public ReactiveProperty<string> Name { get; private set; } | |
public ReactiveProperty<string> BackgroundColor { get; private set; } | |
public event EventHandler Disposed; | |
public PersonViewModel(Person model) | |
{ | |
this.Name = model | |
.ToReactivePropertyAsSynchronized(x => x.Name) | |
.AddTo(this.disposable); | |
this.BackgroundColor = new ReactiveProperty<string>("White"); | |
} | |
public void Dispose() | |
{ | |
if (this.disposable.IsDisposed) { return; } | |
this.disposable.Dispose(); | |
var h = this.Disposed; | |
if (h != null) { h(this, EventArgs.Empty); } | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment