Browse Source

Properly handle context initialization

pull/4917/head
artyom 5 years ago
parent
commit
02bdbd5823
  1. 9
      src/Avalonia.ReactiveUI/ReactiveUserControl.cs
  2. 9
      src/Avalonia.ReactiveUI/ReactiveWindow.cs
  3. 58
      tests/Avalonia.ReactiveUI.UnitTests/ReactiveUserControlTest.cs
  4. 62
      tests/Avalonia.ReactiveUI.UnitTests/ReactiveWindowTest.cs

9
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
/// </summary>
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);
}
/// <summary>

9
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
/// </summary>
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);
}
/// <summary>

58
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<ExampleViewModel> { }
@ -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);
}
}
}

62
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<ExampleViewModel> { }
@ -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);
}
}
}
}

Loading…
Cancel
Save