From 42b77ea99a74b54d5e2cb47086b408cee2d97e74 Mon Sep 17 00:00:00 2001 From: Nathan Povo <17831160+nathanpovo@users.noreply.github.com> Date: Tue, 15 Jun 2021 08:58:25 +0200 Subject: [PATCH 1/8] Observe the Closing event for View deactivation --- .../ActivationForViewFetcher.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs b/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs index c42f730ec8..46a1bcbe14 100644 --- a/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs +++ b/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs @@ -55,9 +55,32 @@ public IObservable GetActivationForView(IActivatableView view) x => fe.Unloaded += x, x => fe.Unloaded -= x); + var windowActivation = GetActivationForWindow(view); + return viewLoaded .Merge(viewUnloaded) .Merge(hitTestVisible) + .Merge(windowActivation) + .DistinctUntilChanged(); + } + + private static IObservable GetActivationForWindow(IActivatableView view) + { + if (view is not Window window) + { + return Observable.Empty; + } + + var viewClosed = Observable.FromEvent( + eventHandler => + { + void Handler(object? sender, EventArgs e) => eventHandler(false); + return Handler; + }, + x => window.Closed += x, + x => window.Closed -= x); + + return viewClosed .DistinctUntilChanged(); } } From 3c337d515137e695bbdf2f08ae5bdd27ca7c09a3 Mon Sep 17 00:00:00 2001 From: Nathan Povo <17831160+nathanpovo@users.noreply.github.com> Date: Tue, 15 Jun 2021 09:20:00 +0200 Subject: [PATCH 2/8] Assert that closing a window deactivates the view --- .../Platforms/wpf/Mocks/WpfTestWindow.cs | 13 ++++++++++++ .../wpf/WpfActivationForViewFetcherTest.cs | 21 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs diff --git a/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs b/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs new file mode 100644 index 0000000000..55061e3409 --- /dev/null +++ b/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2021 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Windows; + +namespace ReactiveUI.Tests.Wpf +{ + public class WpfTestWindow : Window, IActivatableView + { + } +} diff --git a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs index 9faaadd414..06aa589f98 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs +++ b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs @@ -40,6 +40,27 @@ public void FrameworkElementIsActivatedAndDeactivated() new[] { true, false }.AssertAreEqual(activated); } + [Fact] + public void WindowIsActivatedAndDeactivated() + { + var window = new WpfTestWindow(); + var activation = new ActivationForViewFetcher(); + + var obs = activation.GetActivationForView(window); + obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); + + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; + + window.RaiseEvent(loaded); + + new[] { true }.AssertAreEqual(activated); + + window.Close(); + + new[] { true, false }.AssertAreEqual(activated); + } + [Fact] public void IsHitTestVisibleActivatesFrameworkElement() { From e68aa0519e5979031afea6d2bceee2e71b63d0e8 Mon Sep 17 00:00:00 2001 From: Nathan Povo <17831160+nathanpovo@users.noreply.github.com> Date: Fri, 18 Jun 2021 16:46:06 +0200 Subject: [PATCH 3/8] Remove trailing whitespace --- src/ReactiveUI/RegistrationNamespace.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI/RegistrationNamespace.cs b/src/ReactiveUI/RegistrationNamespace.cs index d152b3df8d..ef77a29d2c 100644 --- a/src/ReactiveUI/RegistrationNamespace.cs +++ b/src/ReactiveUI/RegistrationNamespace.cs @@ -12,7 +12,7 @@ public enum RegistrationNamespace { /// No platform to register. None = 0, - + /// /// Xamarin Forms. /// From ec79b77d29c712b7d0aed4a9153bb480f972179a Mon Sep 17 00:00:00 2001 From: Nathan Povo <17831160+nathanpovo@users.noreply.github.com> Date: Fri, 18 Jun 2021 17:01:02 +0200 Subject: [PATCH 4/8] Assert that the window and the control are deactivated This tests that both the window and the child control are deactivated when the application is shut down. --- .../Platforms/wpf/Mocks/WpfTestWindow.cs | 11 ++++++- .../wpf/WpfActivationForViewFetcherTest.cs | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs b/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs index 55061e3409..0807b676c7 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs +++ b/src/ReactiveUI.Tests/Platforms/wpf/Mocks/WpfTestWindow.cs @@ -4,10 +4,19 @@ // See the LICENSE file in the project root for full license information. using System.Windows; - +using System.Windows.Controls; + namespace ReactiveUI.Tests.Wpf { public class WpfTestWindow : Window, IActivatableView { + public WpfTestWindow() + { + RootGrid = new Grid(); + + AddChild(RootGrid); + } + + public Grid RootGrid { get; } } } diff --git a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs index 06aa589f98..10d3bfd16e 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs +++ b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs @@ -61,6 +61,37 @@ public void WindowIsActivatedAndDeactivated() new[] { true, false }.AssertAreEqual(activated); } + [Fact] + public void WindowAndFrameworkElementAreActivatedAndDeactivated() + { + var window = new WpfTestWindow(); + var uc = new WpfTestUserControl(); + + window.RootGrid.Children.Add(uc); + + var activation = new ActivationForViewFetcher(); + + var windowObs = activation.GetActivationForView(window); + windowObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var windowActivated).Subscribe(); + + var ucObs = activation.GetActivationForView(uc); + ucObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var controlActivated).Subscribe(); + + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; + + window.RaiseEvent(loaded); + uc.RaiseEvent(loaded); + + new[] { true }.AssertAreEqual(windowActivated); + new[] { true }.AssertAreEqual(controlActivated); + + window.Dispatcher.InvokeShutdown(); + + new[] { true, false }.AssertAreEqual(windowActivated); + new[] { true, false }.AssertAreEqual(controlActivated); + } + [Fact] public void IsHitTestVisibleActivatesFrameworkElement() { From 1afca4675454afac00712117f51c0b3abcc84200 Mon Sep 17 00:00:00 2001 From: Nathan Povo <17831160+nathanpovo@users.noreply.github.com> Date: Fri, 18 Jun 2021 17:51:48 +0200 Subject: [PATCH 5/8] Use the ShutdownStarted event for view deactivation When an application is shutdown the Unloaded events are not fired. Windows have the Closed event that can be used to know that the view should be deactivated. User controls do not have a Closing event so the dispatcher's ShutdownStarted event has to be used instead. --- .../ActivationForViewFetcher.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs b/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs index 46a1bcbe14..dde03efefb 100644 --- a/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs +++ b/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs @@ -7,6 +7,7 @@ using System.Reactive.Linq; using System.Reflection; using System.Windows; +using System.Windows.Threading; namespace ReactiveUI { @@ -57,10 +58,13 @@ public IObservable GetActivationForView(IActivatableView view) var windowActivation = GetActivationForWindow(view); + var dispatcherActivation = GetActivationForDispatcher(fe); + return viewLoaded .Merge(viewUnloaded) .Merge(hitTestVisible) .Merge(windowActivation) + .Merge(dispatcherActivation) .DistinctUntilChanged(); } @@ -83,5 +87,20 @@ private static IObservable GetActivationForWindow(IActivatableView view) return viewClosed .DistinctUntilChanged(); } + + private static IObservable GetActivationForDispatcher(DispatcherObject dispatcherObject) + { + var dispatcherShutdownStarted = Observable.FromEvent( + eventHandler => + { + void Handler(object? sender, EventArgs e) => eventHandler(false); + return Handler; + }, + x => dispatcherObject.Dispatcher.ShutdownStarted += x, + x => dispatcherObject.Dispatcher.ShutdownStarted -= x); + + return dispatcherShutdownStarted + .DistinctUntilChanged(); + } } } From a4f03841863f0e74a6ad23dd5807724b05226fb8 Mon Sep 17 00:00:00 2001 From: Nathan Povo <17831160+nathanpovo@users.noreply.github.com> Date: Fri, 18 Jun 2021 18:01:38 +0200 Subject: [PATCH 6/8] Remove unnecessary usage of DistinctUntilChanged DistinctUntilChanged is already called on the merged observables. --- src/ReactiveUI.Wpf/ActivationForViewFetcher.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs b/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs index dde03efefb..b07cff5592 100644 --- a/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs +++ b/src/ReactiveUI.Wpf/ActivationForViewFetcher.cs @@ -84,8 +84,7 @@ private static IObservable GetActivationForWindow(IActivatableView view) x => window.Closed += x, x => window.Closed -= x); - return viewClosed - .DistinctUntilChanged(); + return viewClosed; } private static IObservable GetActivationForDispatcher(DispatcherObject dispatcherObject) @@ -99,8 +98,7 @@ private static IObservable GetActivationForDispatcher(DispatcherObject dis x => dispatcherObject.Dispatcher.ShutdownStarted += x, x => dispatcherObject.Dispatcher.ShutdownStarted -= x); - return dispatcherShutdownStarted - .DistinctUntilChanged(); + return dispatcherShutdownStarted; } } } From 72f0ceaf5100429c06e87a4bef65c7e9a1bfd61b Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 20 Jun 2021 19:09:30 +1000 Subject: [PATCH 7/8] Change to update to have STAFact's. --- .../wpf/WpfActivationForViewFetcherTest.cs | 360 +++++++++--------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs index 10d3bfd16e..a576cee4cb 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs +++ b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs @@ -1,182 +1,182 @@ -// Copyright (c) 2021 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Reactive.Concurrency; -using System.Windows; - -using DynamicData; -using Xunit; - -using FactAttribute = Xunit.WpfFactAttribute; - -namespace ReactiveUI.Tests.Wpf -{ - public class WpfActivationForViewFetcherTest - { - [Fact] - public void FrameworkElementIsActivatedAndDeactivated() - { - var uc = new WpfTestUserControl(); - var activation = new ActivationForViewFetcher(); - - var obs = activation.GetActivationForView(uc); - obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); - - var loaded = new RoutedEventArgs(); - loaded.RoutedEvent = FrameworkElement.LoadedEvent; - - uc.RaiseEvent(loaded); - - new[] { true }.AssertAreEqual(activated); - - var unloaded = new RoutedEventArgs(); - unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; - - uc.RaiseEvent(unloaded); - - new[] { true, false }.AssertAreEqual(activated); - } - - [Fact] - public void WindowIsActivatedAndDeactivated() - { - var window = new WpfTestWindow(); - var activation = new ActivationForViewFetcher(); - - var obs = activation.GetActivationForView(window); - obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); - - var loaded = new RoutedEventArgs(); - loaded.RoutedEvent = FrameworkElement.LoadedEvent; - - window.RaiseEvent(loaded); - - new[] { true }.AssertAreEqual(activated); - - window.Close(); - - new[] { true, false }.AssertAreEqual(activated); - } - - [Fact] - public void WindowAndFrameworkElementAreActivatedAndDeactivated() - { - var window = new WpfTestWindow(); - var uc = new WpfTestUserControl(); - - window.RootGrid.Children.Add(uc); - - var activation = new ActivationForViewFetcher(); - - var windowObs = activation.GetActivationForView(window); +// Copyright (c) 2021 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +​ +using System; +using System.Reactive.Concurrency; +using System.Windows; +​ +using DynamicData; +using Xunit; +​ +using FactAttribute = Xunit.WpfFactAttribute; +​ +namespace ReactiveUI.Tests.Wpf +{ + public class WpfActivationForViewFetcherTest + { + [Fact] + public void FrameworkElementIsActivatedAndDeactivated() + { + var uc = new WpfTestUserControl(); + var activation = new ActivationForViewFetcher(); +​ + var obs = activation.GetActivationForView(uc); + obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); +​ + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; +​ + uc.RaiseEvent(loaded); +​ + new[] { true }.AssertAreEqual(activated); +​ + var unloaded = new RoutedEventArgs(); + unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; +​ + uc.RaiseEvent(unloaded); +​ + new[] { true, false }.AssertAreEqual(activated); + } +​ + [Fact] + public void WindowIsActivatedAndDeactivated() + { + var window = new WpfTestWindow(); + var activation = new ActivationForViewFetcher(); +​ + var obs = activation.GetActivationForView(window); + obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); +​ + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; +​ + window.RaiseEvent(loaded); +​ + new[] { true }.AssertAreEqual(activated); +​ + window.Close(); +​ + new[] { true, false }.AssertAreEqual(activated); + } +​ + [StaFact] + public void WindowAndFrameworkElementAreActivatedAndDeactivated() + { + var window = new WpfTestWindow(); + var uc = new WpfTestUserControl(); +​ + window.RootGrid.Children.Add(uc); +​ + var activation = new ActivationForViewFetcher(); +​ + var windowObs = activation.GetActivationForView(window); windowObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var windowActivated).Subscribe(); - +​ var ucObs = activation.GetActivationForView(uc); - ucObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var controlActivated).Subscribe(); - - var loaded = new RoutedEventArgs(); - loaded.RoutedEvent = FrameworkElement.LoadedEvent; - - window.RaiseEvent(loaded); - uc.RaiseEvent(loaded); - - new[] { true }.AssertAreEqual(windowActivated); - new[] { true }.AssertAreEqual(controlActivated); - - window.Dispatcher.InvokeShutdown(); - - new[] { true, false }.AssertAreEqual(windowActivated); - new[] { true, false }.AssertAreEqual(controlActivated); - } - - [Fact] - public void IsHitTestVisibleActivatesFrameworkElement() - { - var uc = new WpfTestUserControl(); - uc.IsHitTestVisible = false; - var activation = new ActivationForViewFetcher(); - - var obs = activation.GetActivationForView(uc); - obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); - - var loaded = new RoutedEventArgs(); - loaded.RoutedEvent = FrameworkElement.LoadedEvent; - - uc.RaiseEvent(loaded); - - // Loaded has happened. - new[] { true }.AssertAreEqual(activated); - - uc.IsHitTestVisible = true; - - // IsHitTestVisible true, we don't want the event to repeat unnecessarily. - new[] { true }.AssertAreEqual(activated); - - var unloaded = new RoutedEventArgs(); - unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; - - uc.RaiseEvent(unloaded); - - // We had both a loaded/hit test visible change/unloaded happen. - new[] { true, false }.AssertAreEqual(activated); - } - - [Fact] - public void IsHitTestVisibleDeactivatesFrameworkElement() - { - var uc = new WpfTestUserControl(); - var activation = new ActivationForViewFetcher(); - - var obs = activation.GetActivationForView(uc); - obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); - - var loaded = new RoutedEventArgs(); - loaded.RoutedEvent = FrameworkElement.LoadedEvent; - - uc.RaiseEvent(loaded); - - new[] { true }.AssertAreEqual(activated); - - uc.IsHitTestVisible = false; - - new[] { true, false }.AssertAreEqual(activated); - } - - [Fact] - public void FrameworkElementIsActivatedAndDeactivatedWithHitTest() - { - var uc = new WpfTestUserControl(); - var activation = new ActivationForViewFetcher(); - - var obs = activation.GetActivationForView(uc); - obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); - - var loaded = new RoutedEventArgs(); - loaded.RoutedEvent = FrameworkElement.LoadedEvent; - - uc.RaiseEvent(loaded); - - new[] { true }.AssertAreEqual(activated); - - // this should deactivate it - uc.IsHitTestVisible = false; - - new[] { true, false }.AssertAreEqual(activated); - - // this should activate it - uc.IsHitTestVisible = true; - - new[] { true, false, true }.AssertAreEqual(activated); - - var unloaded = new RoutedEventArgs(); - unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; - - uc.RaiseEvent(unloaded); - - new[] { true, false, true, false }.AssertAreEqual(activated); - } - } -} + ucObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var controlActivated).Subscribe(); +​ + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; +​ + window.RaiseEvent(loaded); + uc.RaiseEvent(loaded); +​ + new[] { true }.AssertAreEqual(windowActivated); + new[] { true }.AssertAreEqual(controlActivated); +​ + window.Dispatcher.InvokeShutdown(); +​ + new[] { true, false }.AssertAreEqual(windowActivated); + new[] { true, false }.AssertAreEqual(controlActivated); + } +​ + [Fact] + public void IsHitTestVisibleActivatesFrameworkElement() + { + var uc = new WpfTestUserControl(); + uc.IsHitTestVisible = false; + var activation = new ActivationForViewFetcher(); +​ + var obs = activation.GetActivationForView(uc); + obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); +​ + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; +​ + uc.RaiseEvent(loaded); +​ + // Loaded has happened. + new[] { true }.AssertAreEqual(activated); +​ + uc.IsHitTestVisible = true; +​ + // IsHitTestVisible true, we don't want the event to repeat unnecessarily. + new[] { true }.AssertAreEqual(activated); +​ + var unloaded = new RoutedEventArgs(); + unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; +​ + uc.RaiseEvent(unloaded); +​ + // We had both a loaded/hit test visible change/unloaded happen. + new[] { true, false }.AssertAreEqual(activated); + } +​ + [Fact] + public void IsHitTestVisibleDeactivatesFrameworkElement() + { + var uc = new WpfTestUserControl(); + var activation = new ActivationForViewFetcher(); +​ + var obs = activation.GetActivationForView(uc); + obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); +​ + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; +​ + uc.RaiseEvent(loaded); +​ + new[] { true }.AssertAreEqual(activated); +​ + uc.IsHitTestVisible = false; +​ + new[] { true, false }.AssertAreEqual(activated); + } +​ + [Fact] + public void FrameworkElementIsActivatedAndDeactivatedWithHitTest() + { + var uc = new WpfTestUserControl(); + var activation = new ActivationForViewFetcher(); +​ + var obs = activation.GetActivationForView(uc); + obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); +​ + var loaded = new RoutedEventArgs(); + loaded.RoutedEvent = FrameworkElement.LoadedEvent; +​ + uc.RaiseEvent(loaded); +​ + new[] { true }.AssertAreEqual(activated); +​ + // this should deactivate it + uc.IsHitTestVisible = false; +​ + new[] { true, false }.AssertAreEqual(activated); +​ + // this should activate it + uc.IsHitTestVisible = true; +​ + new[] { true, false, true }.AssertAreEqual(activated); +​ + var unloaded = new RoutedEventArgs(); + unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; +​ + uc.RaiseEvent(unloaded); +​ + new[] { true, false, true, false }.AssertAreEqual(activated); + } + } +} From 04a9052a8b50c2c2dd38c5a0f6325fa422c2ce8d Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 20 Jun 2021 19:22:36 +1000 Subject: [PATCH 8/8] remove bad characters --- .../wpf/WpfActivationForViewFetcherTest.cs | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs index a576cee4cb..d430aacdf2 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs +++ b/src/ReactiveUI.Tests/Platforms/wpf/WpfActivationForViewFetcherTest.cs @@ -2,16 +2,16 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -​ + using System; using System.Reactive.Concurrency; using System.Windows; -​ + using DynamicData; using Xunit; -​ + using FactAttribute = Xunit.WpfFactAttribute; -​ + namespace ReactiveUI.Tests.Wpf { public class WpfActivationForViewFetcherTest @@ -21,161 +21,161 @@ public void FrameworkElementIsActivatedAndDeactivated() { var uc = new WpfTestUserControl(); var activation = new ActivationForViewFetcher(); -​ + var obs = activation.GetActivationForView(uc); obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); -​ + var loaded = new RoutedEventArgs(); loaded.RoutedEvent = FrameworkElement.LoadedEvent; -​ + uc.RaiseEvent(loaded); -​ + new[] { true }.AssertAreEqual(activated); -​ + var unloaded = new RoutedEventArgs(); unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; -​ + uc.RaiseEvent(unloaded); -​ + new[] { true, false }.AssertAreEqual(activated); } -​ + [Fact] public void WindowIsActivatedAndDeactivated() { var window = new WpfTestWindow(); var activation = new ActivationForViewFetcher(); -​ + var obs = activation.GetActivationForView(window); obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); -​ + var loaded = new RoutedEventArgs(); loaded.RoutedEvent = FrameworkElement.LoadedEvent; -​ + window.RaiseEvent(loaded); -​ + new[] { true }.AssertAreEqual(activated); -​ + window.Close(); -​ + new[] { true, false }.AssertAreEqual(activated); } -​ + [StaFact] public void WindowAndFrameworkElementAreActivatedAndDeactivated() { var window = new WpfTestWindow(); var uc = new WpfTestUserControl(); -​ + window.RootGrid.Children.Add(uc); -​ + var activation = new ActivationForViewFetcher(); -​ + var windowObs = activation.GetActivationForView(window); windowObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var windowActivated).Subscribe(); -​ + var ucObs = activation.GetActivationForView(uc); ucObs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var controlActivated).Subscribe(); -​ + var loaded = new RoutedEventArgs(); loaded.RoutedEvent = FrameworkElement.LoadedEvent; -​ + window.RaiseEvent(loaded); uc.RaiseEvent(loaded); -​ + new[] { true }.AssertAreEqual(windowActivated); new[] { true }.AssertAreEqual(controlActivated); -​ + window.Dispatcher.InvokeShutdown(); -​ + new[] { true, false }.AssertAreEqual(windowActivated); new[] { true, false }.AssertAreEqual(controlActivated); } -​ + [Fact] public void IsHitTestVisibleActivatesFrameworkElement() { var uc = new WpfTestUserControl(); uc.IsHitTestVisible = false; var activation = new ActivationForViewFetcher(); -​ + var obs = activation.GetActivationForView(uc); obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); -​ + var loaded = new RoutedEventArgs(); loaded.RoutedEvent = FrameworkElement.LoadedEvent; -​ + uc.RaiseEvent(loaded); -​ + // Loaded has happened. new[] { true }.AssertAreEqual(activated); -​ + uc.IsHitTestVisible = true; -​ + // IsHitTestVisible true, we don't want the event to repeat unnecessarily. new[] { true }.AssertAreEqual(activated); -​ + var unloaded = new RoutedEventArgs(); unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; -​ + uc.RaiseEvent(unloaded); -​ + // We had both a loaded/hit test visible change/unloaded happen. new[] { true, false }.AssertAreEqual(activated); } -​ + [Fact] public void IsHitTestVisibleDeactivatesFrameworkElement() { var uc = new WpfTestUserControl(); var activation = new ActivationForViewFetcher(); -​ + var obs = activation.GetActivationForView(uc); obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); -​ + var loaded = new RoutedEventArgs(); loaded.RoutedEvent = FrameworkElement.LoadedEvent; -​ + uc.RaiseEvent(loaded); -​ + new[] { true }.AssertAreEqual(activated); -​ + uc.IsHitTestVisible = false; -​ + new[] { true, false }.AssertAreEqual(activated); } -​ + [Fact] public void FrameworkElementIsActivatedAndDeactivatedWithHitTest() { var uc = new WpfTestUserControl(); var activation = new ActivationForViewFetcher(); -​ + var obs = activation.GetActivationForView(uc); obs.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance).Bind(out var activated).Subscribe(); -​ + var loaded = new RoutedEventArgs(); loaded.RoutedEvent = FrameworkElement.LoadedEvent; -​ + uc.RaiseEvent(loaded); -​ + new[] { true }.AssertAreEqual(activated); -​ + // this should deactivate it uc.IsHitTestVisible = false; -​ + new[] { true, false }.AssertAreEqual(activated); -​ + // this should activate it uc.IsHitTestVisible = true; -​ + new[] { true, false, true }.AssertAreEqual(activated); -​ + var unloaded = new RoutedEventArgs(); unloaded.RoutedEvent = FrameworkElement.UnloadedEvent; -​ + uc.RaiseEvent(unloaded); -​ + new[] { true, false, true, false }.AssertAreEqual(activated); } }