From 965057a7e2af47c0df73f1feb5b71db21ebda923 Mon Sep 17 00:00:00 2001 From: artyom Date: Sat, 13 Oct 2018 20:04:15 +0300 Subject: [PATCH] Fix WhenActivated ignoring WindowBase --- .../AvaloniaActivationForViewFetcher.cs | 34 +++++++++++++++--- .../AvaloniaActivationForViewFetcherTest.cs | 35 +++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs b/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs index 828d8024e6..cf386a235e 100644 --- a/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs +++ b/src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Reactive.Linq; using Avalonia; using Avalonia.VisualTree; +using Avalonia.Controls; using ReactiveUI; namespace Avalonia @@ -20,18 +21,41 @@ namespace Avalonia public IObservable GetActivationForView(IActivatable view) { if (!(view is IVisual visual)) return Observable.Return(false); - var viewLoaded = Observable + if (view is WindowBase window) return GetActivationForWindowBase(window); + return GetActivationForVisual(visual); + } + + private IObservable GetActivationForWindowBase(WindowBase window) + { + var windowLoaded = Observable + .FromEventPattern( + x => window.Initialized += x, + x => window.Initialized -= x) + .Select(args => true); + var windowUnloaded = Observable + .FromEventPattern( + x => window.Closed += x, + x => window.Closed -= x) + .Select(args => false); + return windowLoaded + .Merge(windowUnloaded) + .DistinctUntilChanged(); + } + + private IObservable GetActivationForVisual(IVisual visual) + { + var visualLoaded = Observable .FromEventPattern( x => visual.AttachedToVisualTree += x, - x => visual.DetachedFromVisualTree -= x) + x => visual.AttachedToVisualTree -= x) .Select(args => true); - var viewUnloaded = Observable + var visualUnloaded = Observable .FromEventPattern( x => visual.DetachedFromVisualTree += x, x => visual.DetachedFromVisualTree -= x) .Select(args => false); - return viewLoaded - .Merge(viewUnloaded) + return visualLoaded + .Merge(visualUnloaded) .DistinctUntilChanged(); } } diff --git a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs b/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs index 97701f8437..bda55276a8 100644 --- a/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs +++ b/tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs @@ -32,6 +32,21 @@ namespace Avalonia } } + public class TestWindowWithWhenActivated : Window, IActivatable + { + public bool Active { get; private set; } + + public TestWindowWithWhenActivated() + { + this.WhenActivated(disposables => { + Active = true; + Disposable + .Create(() => Active = false) + .DisposeWith(disposables); + }); + } + } + [Fact] public void Visual_Element_Is_Activated_And_Deactivated() { @@ -85,5 +100,25 @@ namespace Avalonia fakeRenderedDecorator.Child = null; Assert.False(userControl.Active); } + + [Fact] + public void Activation_For_View_Fetcher_Should_Support_Windows() + { + Locator.CurrentMutable.RegisterConstant( + new AvaloniaActivationForViewFetcher(), + typeof(IActivationForViewFetcher)); + + using (var application = UnitTestApplication.Start(TestServices.MockWindowingPlatform)) + { + var window = new TestWindowWithWhenActivated(); + Assert.False(window.Active); + + window.Show(); + Assert.True(window.Active); + + window.Close(); + Assert.False(window.Active); + } + } } } \ No newline at end of file