-

   predefglas

 - e-mail

 

 -

 LiveInternet.ru:
: 10.12.2014
:
:
: 94

:

( 27432 )


(0)

ReactiveUI:

, 23 2016 . 19:35 +
, ! 1: ReactiveUI: ViewModel ViewModel, , ReactiveUI. , . , . , , , . , , . , . : private string _firstName; public string FirstName { get { return _firstName; } set { this.RaiseAndSetIfChanged(ref _firstName, value); } } 6 , . e C# , . ? Fody , IL- . , . ReactiveUI : ReactiveUI.Fody. . , : PropertyChanged, , RaiseAndSetIfChanged(). NuGet: > Install-Package ReactiveUI.Fody FodyWeavers.xml. : <?xml > : [Reactive] public string FirstName { get; set; } FullName ObservableAsPropertyHelper<>. GitHub, . , , ToProperty() , ReactiveUI.Fody . , . ? -. ReactiveUI , A MVVM framework <...> to create elegant, testable User Interfaces.... , , - . Observable.FromEventPattern(), IObservable<> . IObservable<> , .CreateCollection(). , , OnComplete() Dispose(), IObservable<> , . , , , . , , .ToList(), , , OnComplete(), . [Test] public void FirstName_WhenChanged_RaisesPropertyChangedEventForFirstNameAndFullNameProperties() { var vm = new PersonViewModel("FirstName", "LastName"); var evendObservable = Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>( a => vm.PropertyChanged > ( ) using, . , - . , , . , IObservable<> Changed . [Test] public void FirstName_WhenChanged_PushesToPropertyChangedObservableForFirstNameAndFullNameProperties() { var vm = new PersonViewModel("FirstName", "LastName"); var notifications = vm.Changed.CreateCollection(); using (notifications) { vm.FirstName = "NewFirstName"; } Assert.That(vm.FullName, Is.EqualTo("NewFirstName LastName")); Assert.That(notifications, Has.Count.EqualTo(2)); Assert.That(notifications[0].Sender, Is.SameAs(vm)); Assert.That(notifications[0].PropertyName, Is.EqualTo(nameof(PersonViewModel.FirstName))); Assert.That(notifications[1].Sender, Is.SameAs(vm)); Assert.That(notifications[1].PropertyName, Is.EqualTo(nameof(PersonViewModel.FullName))); } ȅ . ! , : vm.Changed.Subscribe(n => Console.WriteLine(n.PropertyName)); vm.FirstName = "OMG"; : FullName FirstName . , , , . : . , . , , . , , , , . . , , ReactiveUI.Fody . . INotifyPropertyChanged, , , , , - . , (, ), ? , , , ? , , , . , . , , - . , : public interface INotifyCollectionChanged { /// <summary>Occurs when the collection changes.</summary> event NotifyCollectionChangedEventHandler CollectionChanged; } , // .. CollectionChanged. , , . .NET , ReactiveUI. ? : IReactiveList<T>, IReadOnlyReactiveList<T>, IReadOnlyReactiveCollection<T>, IReactiveCollection<T>, IReactiveNotifyCollectionChanged<T>, IReactiveNotifyCollectionItemChanged<T>. , , , . . : ReactiveList<T>. . , . ! , , , , . . , INotifyCollectionChanged, INotifyPropertyChanged *Changind, , -- , , - . . : var list = new ReactiveList<string>(); list.BeforeItemsAdded.Subscribe(e => Console.WriteLine($"Before added: {e}")); list.ItemsAdded.Subscribe(e => Console.WriteLine($"Added: {e}")); list.BeforeItemsRemoved.Subscribe(e => Console.WriteLine($"Before removed: {e}")); list.ItemsRemoved.Subscribe(e => Console.WriteLine($"Removed: {e}")); list.CountChanging.Subscribe(e => Console.WriteLine($"Count changing: {e}")); list.CountChanged.Subscribe(e => Console.WriteLine($"Count changed: {e}")); list.IsEmptyChanged.Subscribe(e => Console.WriteLine($"IsEmpty changed: {e}")); Console.WriteLine("# Add 'first'"); list.Add("first"); Console.WriteLine("\n# Add 'second'"); list.Add("second"); Console.WriteLine("\n# Remove 'first'"); list.Remove("first"); : #Add 'first' Count changing: 0 Before added: first Count changed: 1 IsEmpty changed: False Added: first #Add 'second' Count changing: 1 Before added: second Count changed: 2 Added: second #Remove 'first' Count changing: 2 Before removed: first Count changed: 1 Removed: first , , . : ItemsAdded/ItemsRemoved/BeforeItemsAdded/BeforeItemsRemoved / CountChanging/CountChanged IsEmptyChanged . , . ? var count = 0; var list = new ReactiveList<int>(); list.ItemsAdded.Subscribe(e => count++); list.ItemsRemoved.Subscribe(e => count--); for (int i = 0; i < 100; i++) { list.Add(i); } for (int i = 0; i < 100; > . , : list.AddRange(Enumerable.Range(0, 10)); list.RemoveAll(Enumerable.Range(0, 5).Select(i => i * 2)); . , . list.AddRange(Enumerable.Range(0, 100)); list.RemoveAll(Enumerable.Range(0, 50).Select(i => i * 2)); ! count > , ReactiveList<T> , . , , , : list.ShouldReset.Subscribe(_ => Console.WriteLine("ShouldReset")); ? : , 100 , . , , . . ShouldReset IObservable<Unit>. Unit void, . , , , , - . . , , . , , - : list.ItemsAdded.Subscribe(e => count++); list.ItemsRemoved.Subscribe(e => count--); list.ShouldReset.Subscribe(_ => count = list.Count); . , , . , , , . , . ? ReactiveList<T> : double resetChangeThreshold = 0.3. ResetChangeThreshold. ? , / , / 10. , . 100/0 > 0.3 50/100 > 0.3, . , ResetChangeThreshold . ? : for (int i = 0; i < 100; i++) { list.Add(i); } -, . . ? SuppressChangeNotifications(). , using, : using (list.SuppressChangeNotifications()) { for (int i = 0; i < 100; i++) { list.Add(i); } } ? , ReactiveList<T> ItemChanged ItemChanging . : var list = new ReactiveList<PersonViewModel>(); list.ItemChanged.Subscribe(e => Console.WriteLine(e.PropertyName)); var vm = new PersonViewModel("Name", "Surname"); list.Add(vm); vm.FirstName = "NewName"; . , ReactiveList ? , -. , : var list = new ReactiveList<PersonViewModel>() { ChangeTrackingEnabled = true }; : FullName FirstName , . , . , / . , , , ? . , ReactiveUI , . DerivedCollection. ReactiveList , , , , . , . , . , . var list = new ReactiveList<int>(); list.AddRange(Enumerable.Range(1, 5)); var derived = list.CreateDerivedCollection( selector: i => i*2, filter: i => i % 2 > , , ( !) . , . , INotifyCollectionChanged, IEnumerable<>. . , . : 1, 2, 3, 4, 5 10, 6, 2 1, 2, 3, 4, 5, 2, 3, 4 10, 6, 6, 2 Stay tuned , . , , , . . , ReactiveList . , , . , , , , . . , . View + ViewModel GUI, . !

:  

 : [1]