diff --git a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs
index a401d62a06..5430d288bc 100644
--- a/src/Avalonia.ReactiveUI/ReactiveUserControl.cs
+++ b/src/Avalonia.ReactiveUI/ReactiveUserControl.cs
@@ -1,4 +1,6 @@
using System;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
@@ -22,10 +24,13 @@ namespace Avalonia.ReactiveUI
///
public ReactiveUserControl()
{
- this.WhenAnyValue(x => x.DataContext)
- .Subscribe(context => ViewModel = context as TViewModel);
+ this.WhenActivated(disposables => { });
this.WhenAnyValue(x => x.ViewModel)
+ .Skip(1)
.Subscribe(model => DataContext = model);
+ this.WhenAnyValue(x => x.DataContext)
+ .Skip(1)
+ .Subscribe(context => ViewModel = context as TViewModel);
}
///
diff --git a/src/Avalonia.ReactiveUI/ReactiveWindow.cs b/src/Avalonia.ReactiveUI/ReactiveWindow.cs
index 896795f42d..0a25d66af8 100644
--- a/src/Avalonia.ReactiveUI/ReactiveWindow.cs
+++ b/src/Avalonia.ReactiveUI/ReactiveWindow.cs
@@ -1,4 +1,6 @@
using System;
+using System.Reactive.Disposables;
+using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using Avalonia.Controls;
@@ -22,10 +24,13 @@ namespace Avalonia.ReactiveUI
///
public ReactiveWindow()
{
- this.WhenAnyValue(x => x.DataContext)
- .Subscribe(context => ViewModel = context as TViewModel);
+ this.WhenActivated(disposables => { });
this.WhenAnyValue(x => x.ViewModel)
+ .Skip(1)
.Subscribe(model => DataContext = model);
+ this.WhenAnyValue(x => x.DataContext)
+ .Skip(1)
+ .Subscribe(context => ViewModel = context as TViewModel);
}
///
diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs
index 026a08874f..5d257f75f2 100644
--- a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs
+++ b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs
@@ -1,3 +1,4 @@
+using System.Reactive.Disposables;
using Avalonia.UnitTests;
using ReactiveUI;
using Splat;
@@ -7,7 +8,20 @@ namespace Avalonia.ReactiveUI.UnitTests
{
public class ReactiveUserControlTest
{
- public class ExampleViewModel : ReactiveObject { }
+ public class ExampleViewModel : ReactiveObject, IActivatableViewModel
+ {
+ public bool IsActive { get; private set; }
+
+ public ViewModelActivator Activator { get; } = new ViewModelActivator();
+
+ public ExampleViewModel() => this.WhenActivated(disposables =>
+ {
+ IsActive = true;
+ Disposable
+ .Create(() => IsActive = false)
+ .DisposeWith(disposables);
+ });
+ }
public class ExampleView : ReactiveUserControl { }
@@ -44,5 +58,47 @@ namespace Avalonia.ReactiveUI.UnitTests
Assert.Null(view.ViewModel);
Assert.Null(view.DataContext);
}
+
+ [Fact]
+ public void Should_Start_With_NotNull_Activated_ViewModel()
+ {
+ var root = new TestRoot();
+ var view = new ExampleView {ViewModel = new ExampleViewModel()};
+
+ Assert.False(view.ViewModel.IsActive);
+
+ root.Child = view;
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.True(view.ViewModel.IsActive);
+
+ root.Child = null;
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.False(view.ViewModel.IsActive);
+ }
+
+ [Fact]
+ public void Should_Start_With_NotNull_Activated_DataContext()
+ {
+ var root = new TestRoot();
+ var view = new ExampleView {DataContext = new ExampleViewModel()};
+
+ Assert.False(view.ViewModel.IsActive);
+
+ root.Child = view;
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.True(view.ViewModel.IsActive);
+
+ root.Child = null;
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.False(view.ViewModel.IsActive);
+ }
}
}
diff --git a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs
index 7612c07aae..18a8a33f09 100644
--- a/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs
+++ b/tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs
@@ -1,3 +1,4 @@
+using System.Reactive.Disposables;
using Avalonia.UnitTests;
using ReactiveUI;
using Splat;
@@ -7,7 +8,20 @@ namespace Avalonia.ReactiveUI.UnitTests
{
public class ReactiveWindowTest
{
- public class ExampleViewModel : ReactiveObject { }
+ public class ExampleViewModel : ReactiveObject, IActivatableViewModel
+ {
+ public bool IsActive { get; private set; }
+
+ public ViewModelActivator Activator { get; } = new ViewModelActivator();
+
+ public ExampleViewModel() => this.WhenActivated(disposables =>
+ {
+ IsActive = true;
+ Disposable
+ .Create(() => IsActive = false)
+ .DisposeWith(disposables);
+ });
+ }
public class ExampleWindow : ReactiveWindow { }
@@ -47,5 +61,51 @@ namespace Avalonia.ReactiveUI.UnitTests
Assert.Null(view.DataContext);
}
}
+
+ [Fact]
+ public void Should_Start_With_NotNull_Activated_ViewModel()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var view = new ExampleWindow { ViewModel = new ExampleViewModel() };
+
+ Assert.False(view.ViewModel.IsActive);
+
+ view.Show();
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.True(view.ViewModel.IsActive);
+
+ view.Close();
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.False(view.ViewModel.IsActive);
+ }
+ }
+
+ [Fact]
+ public void Should_Start_With_NotNull_Activated_DataContext()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var view = new ExampleWindow { DataContext = new ExampleViewModel() };
+
+ Assert.False(view.ViewModel.IsActive);
+
+ view.Show();
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.True(view.ViewModel.IsActive);
+
+ view.Close();
+
+ Assert.NotNull(view.ViewModel);
+ Assert.NotNull(view.DataContext);
+ Assert.False(view.ViewModel.IsActive);
+ }
+ }
}
}