diff --git a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs index fc48a8853d..24aba6b650 100644 --- a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs +++ b/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 /// 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); } /// diff --git a/src/Avalonia.ReactiveUI/ReactiveWindow.cs b/src/Avalonia.ReactiveUI/ReactiveWindow.cs index 5695a727af..a412f8e383 100644 --- a/src/Avalonia.ReactiveUI/ReactiveWindow.cs +++ b/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 /// 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); } /// diff --git a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs index fdf8a858bd..c66a3c4ba1 100644 --- a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs +++ b/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() diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs index b57bb242bd..026a08874f 100644 --- a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs +++ b/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 { } + 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); } } -} \ No newline at end of file +} diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs index 3a5c562a59..7612c07aae 100644 --- a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs +++ b/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 { } + 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); } } } -} \ No newline at end of file +}