Browse Source

TwoWay DataContext and ViewModel sync

pull/4917/head
artyom 5 years ago
parent
commit
f2cb6d7557
  1. 6
      src/Avalonia.ReactiveUI/ReactiveUserControl.cs
  2. 6
      src/Avalonia.ReactiveUI/ReactiveWindow.cs
  3. 12
      tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs
  4. 21
      tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs
  5. 25
      tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs

6
src/Avalonia.ReactiveUI/ReactiveUserControl.cs

@ -1,3 +1,4 @@
using System;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
@ -20,7 +21,10 @@ namespace Avalonia.ReactiveUI
/// </summary>
public ReactiveUserControl()
{
DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel;
this.WhenAnyValue(x => x.DataContext)
.Subscribe(context => ViewModel = context as TViewModel);
this.WhenAnyValue(x => x.ViewModel)
.Subscribe(model => DataContext = model);
}
/// <summary>

6
src/Avalonia.ReactiveUI/ReactiveWindow.cs

@ -1,3 +1,4 @@
using System;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
@ -20,7 +21,10 @@ namespace Avalonia.ReactiveUI
/// </summary>
public ReactiveWindow()
{
DataContextChanged += (sender, args) => ViewModel = DataContext as TViewModel;
this.WhenAnyValue(x => x.DataContext)
.Subscribe(context => ViewModel = context as TViewModel);
this.WhenAnyValue(x => x.ViewModel)
.Subscribe(model => DataContext = model);
}
/// <summary>

12
tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs

@ -88,12 +88,12 @@ namespace Avalonia.ReactiveUI.UnitTests
}
}
public AvaloniaActivationForViewFetcherTest()
{
Locator.CurrentMutable.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
}
public AvaloniaActivationForViewFetcherTest() =>
Locator
.CurrentMutable
.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
[Fact]
public void Visual_Element_Is_Activated_And_Deactivated()

21
tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs

@ -1,4 +1,3 @@
using Avalonia.Controls;
using Avalonia.UnitTests;
using ReactiveUI;
using Splat;
@ -12,10 +11,20 @@ namespace Avalonia.ReactiveUI.UnitTests
public class ExampleView : ReactiveUserControl<ExampleViewModel> { }
public ReactiveUserControlTest() =>
Locator
.CurrentMutable
.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
[Fact]
public void Data_Context_Should_Stay_In_Sync_With_Reactive_User_Control_View_Model()
{
var root = new TestRoot();
var view = new ExampleView();
root.Child = view;
var viewModel = new ExampleViewModel();
Assert.Null(view.ViewModel);
@ -26,6 +35,14 @@ namespace Avalonia.ReactiveUI.UnitTests
view.DataContext = null;
Assert.Null(view.ViewModel);
Assert.Null(view.DataContext);
view.ViewModel = viewModel;
Assert.Equal(viewModel, view.ViewModel);
Assert.Equal(viewModel, view.DataContext);
view.ViewModel = null;
Assert.Null(view.ViewModel);
Assert.Null(view.DataContext);
}
}
}
}

25
tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs

@ -1,4 +1,3 @@
using Avalonia.Controls;
using Avalonia.UnitTests;
using ReactiveUI;
using Splat;
@ -12,6 +11,13 @@ namespace Avalonia.ReactiveUI.UnitTests
public class ExampleWindow : ReactiveWindow<ExampleViewModel> { }
public ReactiveWindowTest() =>
Locator
.CurrentMutable
.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
[Fact]
public void Data_Context_Should_Stay_In_Sync_With_Reactive_Window_View_Model()
{
@ -19,16 +25,27 @@ namespace Avalonia.ReactiveUI.UnitTests
{
var view = new ExampleWindow();
var viewModel = new ExampleViewModel();
view.Show();
Assert.Null(view.ViewModel);
Assert.Null(view.DataContext);
view.DataContext = viewModel;
Assert.Equal(view.ViewModel, viewModel);
Assert.Equal(view.DataContext, viewModel);
Assert.Equal(viewModel, view.ViewModel);
Assert.Equal(viewModel, view.DataContext);
view.DataContext = null;
Assert.Null(view.ViewModel);
Assert.Null(view.DataContext);
view.ViewModel = viewModel;
Assert.Equal(viewModel, view.ViewModel);
Assert.Equal(viewModel, view.DataContext);
view.ViewModel = null;
Assert.Null(view.ViewModel);
Assert.Null(view.DataContext);
}
}
}
}
}

Loading…
Cancel
Save