diff --git a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
index 2defb52d4526..4e22034af3de 100644
--- a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
@@ -222,6 +222,7 @@ Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.SetResponse(int cod
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.Uri.get -> System.Uri!
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(Microsoft.Maui.Controls.PlatformWebViewWebResourceRequestedEventArgs! platformArgs) -> void
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(System.Uri! uri, string! method) -> void
+Microsoft.Maui.Controls.Window.IsActivated.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.set -> void
Microsoft.Maui.Controls.Window.IsMinimizable.get -> bool
@@ -465,6 +466,7 @@ static readonly Microsoft.Maui.Controls.Border.SafeAreaEdgesProperty -> Microsof
~static readonly Microsoft.Maui.Controls.TemplatedView.IsClippedToBoundsProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TemplatedView.PaddingProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TimePicker.IsOpenProperty -> Microsoft.Maui.Controls.BindableProperty
+static readonly Microsoft.Maui.Controls.Window.IsActivatedProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMaximizableProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMinimizableProperty -> Microsoft.Maui.Controls.BindableProperty!
~virtual Microsoft.Maui.Controls.BindableProperty.BindingPropertyChangedDelegate.Invoke(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue) -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
index 8bf7455b58fa..a765cb09c70d 100644
--- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
@@ -207,6 +207,7 @@ Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.SetResponse(int cod
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.Uri.get -> System.Uri!
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(Microsoft.Maui.Controls.PlatformWebViewWebResourceRequestedEventArgs! platformArgs) -> void
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(System.Uri! uri, string! method) -> void
+Microsoft.Maui.Controls.Window.IsActivated.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.set -> void
Microsoft.Maui.Controls.Window.IsMinimizable.get -> bool
@@ -453,6 +454,7 @@ static readonly Microsoft.Maui.Controls.Border.SafeAreaEdgesProperty -> Microsof
~static readonly Microsoft.Maui.Controls.TemplatedView.IsClippedToBoundsProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TemplatedView.PaddingProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TimePicker.IsOpenProperty -> Microsoft.Maui.Controls.BindableProperty
+static readonly Microsoft.Maui.Controls.Window.IsActivatedProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMaximizableProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMinimizableProperty -> Microsoft.Maui.Controls.BindableProperty!
~virtual Microsoft.Maui.Controls.BindableProperty.BindingPropertyChangedDelegate.Invoke(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue) -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
index 8bf7455b58fa..a765cb09c70d 100644
--- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
@@ -207,6 +207,7 @@ Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.SetResponse(int cod
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.Uri.get -> System.Uri!
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(Microsoft.Maui.Controls.PlatformWebViewWebResourceRequestedEventArgs! platformArgs) -> void
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(System.Uri! uri, string! method) -> void
+Microsoft.Maui.Controls.Window.IsActivated.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.set -> void
Microsoft.Maui.Controls.Window.IsMinimizable.get -> bool
@@ -453,6 +454,7 @@ static readonly Microsoft.Maui.Controls.Border.SafeAreaEdgesProperty -> Microsof
~static readonly Microsoft.Maui.Controls.TemplatedView.IsClippedToBoundsProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TemplatedView.PaddingProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TimePicker.IsOpenProperty -> Microsoft.Maui.Controls.BindableProperty
+static readonly Microsoft.Maui.Controls.Window.IsActivatedProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMaximizableProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMinimizableProperty -> Microsoft.Maui.Controls.BindableProperty!
~virtual Microsoft.Maui.Controls.BindableProperty.BindingPropertyChangedDelegate.Invoke(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue) -> void
diff --git a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
index 0fbfb8cf3540..fe8baa26b87d 100644
--- a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
@@ -216,6 +216,7 @@ Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.SetResponse(int cod
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.Uri.get -> System.Uri!
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(Microsoft.Maui.Controls.PlatformWebViewWebResourceRequestedEventArgs! platformArgs) -> void
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(System.Uri! uri, string! method) -> void
+Microsoft.Maui.Controls.Window.IsActivated.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.set -> void
Microsoft.Maui.Controls.Window.IsMinimizable.get -> bool
@@ -456,6 +457,7 @@ static readonly Microsoft.Maui.Controls.Border.SafeAreaEdgesProperty -> Microsof
~static readonly Microsoft.Maui.Controls.TemplatedView.IsClippedToBoundsProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TemplatedView.PaddingProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TimePicker.IsOpenProperty -> Microsoft.Maui.Controls.BindableProperty
+static readonly Microsoft.Maui.Controls.Window.IsActivatedProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMaximizableProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMinimizableProperty -> Microsoft.Maui.Controls.BindableProperty!
~virtual Microsoft.Maui.Controls.BindableProperty.BindingPropertyChangedDelegate.Invoke(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue) -> void
diff --git a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
index 112869fc21bf..c98a7b3105c1 100644
--- a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
@@ -199,6 +199,7 @@ Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.SetResponse(int cod
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.Uri.get -> System.Uri!
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(Microsoft.Maui.Controls.PlatformWebViewWebResourceRequestedEventArgs! platformArgs) -> void
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(System.Uri! uri, string! method) -> void
+Microsoft.Maui.Controls.Window.IsActivated.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.set -> void
Microsoft.Maui.Controls.Window.IsMinimizable.get -> bool
@@ -435,6 +436,7 @@ static readonly Microsoft.Maui.Controls.Border.SafeAreaEdgesProperty -> Microsof
~static readonly Microsoft.Maui.Controls.TemplatedView.IsClippedToBoundsProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TemplatedView.PaddingProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TimePicker.IsOpenProperty -> Microsoft.Maui.Controls.BindableProperty
+static readonly Microsoft.Maui.Controls.Window.IsActivatedProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMaximizableProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMinimizableProperty -> Microsoft.Maui.Controls.BindableProperty!
~virtual Microsoft.Maui.Controls.BindableProperty.BindingPropertyChangedDelegate.Invoke(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue) -> void
diff --git a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
index 112869fc21bf..c98a7b3105c1 100644
--- a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
+++ b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt
@@ -199,6 +199,7 @@ Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.SetResponse(int cod
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.Uri.get -> System.Uri!
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(Microsoft.Maui.Controls.PlatformWebViewWebResourceRequestedEventArgs! platformArgs) -> void
Microsoft.Maui.Controls.WebViewWebResourceRequestedEventArgs.WebViewWebResourceRequestedEventArgs(System.Uri! uri, string! method) -> void
+Microsoft.Maui.Controls.Window.IsActivated.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.get -> bool
Microsoft.Maui.Controls.Window.IsMaximizable.set -> void
Microsoft.Maui.Controls.Window.IsMinimizable.get -> bool
@@ -435,6 +436,7 @@ static readonly Microsoft.Maui.Controls.Border.SafeAreaEdgesProperty -> Microsof
~static readonly Microsoft.Maui.Controls.TemplatedView.IsClippedToBoundsProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TemplatedView.PaddingProperty -> Microsoft.Maui.Controls.BindableProperty
~static readonly Microsoft.Maui.Controls.TimePicker.IsOpenProperty -> Microsoft.Maui.Controls.BindableProperty
+static readonly Microsoft.Maui.Controls.Window.IsActivatedProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMaximizableProperty -> Microsoft.Maui.Controls.BindableProperty!
static readonly Microsoft.Maui.Controls.Window.IsMinimizableProperty -> Microsoft.Maui.Controls.BindableProperty!
~virtual Microsoft.Maui.Controls.BindableProperty.BindingPropertyChangedDelegate.Invoke(Microsoft.Maui.Controls.BindableObject bindable, object oldValue, object newValue) -> void
diff --git a/src/Controls/src/Core/Window/Window.cs b/src/Controls/src/Core/Window/Window.cs
index af82bb140fc9..b4a744343101 100644
--- a/src/Controls/src/Core/Window/Window.cs
+++ b/src/Controls/src/Core/Window/Window.cs
@@ -14,6 +14,12 @@ namespace Microsoft.Maui.Controls
[ContentProperty(nameof(Page))]
public partial class Window : NavigableElement, IWindow, IToolbarElement, IMenuBarElement, IFlowDirectionController, IWindowController
{
+ static readonly BindablePropertyKey IsActivatedPropertyKey =
+ BindableProperty.CreateReadOnly(nameof(IsActivated), typeof(bool), typeof(Window), false, propertyChanged: OnIsActivatedPropertyChanged);
+
+ /// Bindable property for .
+ public static readonly BindableProperty IsActivatedProperty = IsActivatedPropertyKey.BindableProperty;
+
/// Bindable property for .
public static readonly BindableProperty TitleProperty = BindableProperty.Create(
nameof(Title), typeof(string), typeof(Window), default(string?));
@@ -76,7 +82,6 @@ public partial class Window : NavigableElement, IWindow, IToolbarElement, IMenuB
List _visualChildren;
Toolbar? _toolbar;
MenuBarTracker _menuBarTracker;
- bool _isActivated;
IToolbar? IToolbarElement.Toolbar => Toolbar;
internal Toolbar? Toolbar
@@ -117,6 +122,12 @@ public string? Title
set => SetValue(TitleProperty, value);
}
+ public bool IsActivated
+ {
+ get => (bool)GetValue(IsActivatedProperty);
+ private set => SetValue(IsActivatedPropertyKey, value);
+ }
+
string? ITitledElement.Title => Title ?? (Page as Shell)?.Title;
public Page? Page
@@ -324,24 +335,6 @@ public bool RemoveOverlay(IWindowOverlay overlay)
internal IMauiContext MauiContext =>
Handler?.MauiContext ?? throw new InvalidOperationException("MauiContext is null.");
- internal bool IsActivated
- {
- get
- {
- return _isActivated;
- }
- private set
- {
- if (_isActivated == value)
- return;
-
- _isActivated = value;
-
- if (value)
- SendWindowAppearing();
- }
- }
-
internal bool IsDestroyed { get; private set; }
internal bool IsCreated { get; private set; }
@@ -634,6 +627,15 @@ static void OnPageChanging(BindableObject bindable, object oldValue, object newV
oldPage.SendDisappearing();
}
+ static void OnIsActivatedPropertyChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ var window = (Window)bindable;
+ if ((bool)newValue)
+ {
+ window.SendWindowAppearing();
+ }
+ }
+
void OnPageChanged(Page? oldPage, Page? newPage)
{
if (oldPage != null)
diff --git a/src/Controls/tests/Core.UnitTests/WindowsTests.cs b/src/Controls/tests/Core.UnitTests/WindowsTests.cs
index 3f9599e00ec4..d63f48204ea4 100644
--- a/src/Controls/tests/Core.UnitTests/WindowsTests.cs
+++ b/src/Controls/tests/Core.UnitTests/WindowsTests.cs
@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.Maui.Graphics;
using Xunit;
@@ -649,6 +650,74 @@ public void PreviousShellDisconnectsFromWindowPropertyChanged()
Assert.False(fired);
}
+ [Fact]
+ public void CreateWindowKeepIsActivatedIsFalse()
+ {
+ var app = new TestApp();
+
+ var window = app.CreateWindow();
+
+ Assert.False(window.IsActivated);
+ }
+
+ [Fact]
+ public void ActivateWindowWillSetIsActiveToTrue()
+ {
+ var app = new TestApp();
+
+ var window = app.CreateWindow();
+
+ (window as IWindow).Activated();
+
+ Assert.True(window.IsActivated);
+ }
+
+ [Fact]
+ public void ActivateWindowAndDeactivateWillSetIsActiveToFalse()
+ {
+ var app = new TestApp();
+
+ var window = app.CreateWindow();
+
+ (window as IWindow).Activated();
+
+ Assert.True(window.IsActivated);
+
+ (window as IWindow).Deactivated();
+
+ Assert.False(window.IsActivated);
+ }
+
+ [Fact]
+ public async Task ActivateWindowSendAppearingOnPage()
+ {
+ var app = new TestApp();
+
+ var window = app.CreateWindow();
+
+ var page = new ContentPage();
+
+ window.Page = page;
+
+ page.SendDisappearing();
+
+ var tcs = new TaskCompletionSource();
+
+ using var cts = new CancellationTokenSource();
+ using var _ = cts.Token.Register(() => tcs.SetResult(false));
+
+ page.Appearing += (_, __) =>
+ {
+ tcs.SetResult(true);
+ };
+
+ cts.CancelAfter(TimeSpan.FromSeconds(5));
+
+ (window as IWindow).Activated();
+
+ Assert.True(await tcs.Task);
+ }
+
[Theory]
[InlineData(double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN, double.NaN)]
[InlineData(-1, -1, -1, -1, -1, -1, double.NaN, double.NaN)]
@@ -766,5 +835,34 @@ public async Task TwoKeysSameWindow()
Assert.Same(window, actual);
Assert.Empty(table);
}
+
+ [Fact]
+ public void BindingIsActivatedProperty()
+ {
+ var app = new TestApp();
+ var page = new ContentPage();
+ var window = app.CreateWindow();
+ window.Page = page;
+
+ var vm = new ViewModel();
+ window.BindingContext = vm;
+ window.SetBinding(Window.IsActivatedProperty, nameof(vm.IsWindowActive));
+
+ (window as IWindow).Activated();
+
+ Assert.True(vm.IsWindowActive);
+
+ (window as IWindow).Deactivated();
+
+ Assert.False(vm.IsWindowActive);
+ }
+ }
+
+ class ViewModel
+ {
+ public bool IsWindowActive
+ {
+ get; set;
+ }
}
}
diff --git a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs
index fca282fbbe4e..dbe5533fe0e1 100644
--- a/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs
+++ b/src/Controls/tests/DeviceTests/Elements/Window/WindowTests.cs
@@ -232,5 +232,57 @@ await firstPage.Handler.MauiContext.Services.GetRequiredService()
Assert.True(passed);
}
+
+ [Fact]
+ public async Task WindowIsActivedRespondToMethodsCall()
+ {
+ SetupBuilder();
+ var page = new ContentPage();
+ var window = new Window(page);
+
+ await CreateHandlerAndAddToWindow(window, (h) =>
+ {
+ var w = h.VirtualView;
+
+ Assert.True(window.IsActivated);
+
+ w.Deactivated();
+
+ Assert.False(window.IsActivated);
+ });
+ }
+
+ [Fact]
+ public async Task SwitchBetweenWindowShouldTriggerIsActivated()
+ {
+ SetupBuilder();
+ var page = new ContentPage();
+ var app = ApplicationServices.GetService() as ApplicationStub;
+
+ var window1 = new Window(page);
+ var window2 = new Window(page);
+
+ await CreateHandlerAndAddToWindow(window1, (h) =>
+ {
+ app.OpenWindow(window1);
+ Assert.True(window1.IsActivated);
+ Assert.False(window2.IsActivated);
+ });
+
+
+ await CreateHandlerAndAddToWindow(window2, (h) =>
+ {
+ app.OpenWindow(window2);
+
+ Assert.False(window1.IsActivated);
+ Assert.True(window2.IsActivated);
+ });
+
+ app.CloseWindow(window2);
+ app.CloseWindow(window1);
+
+ Assert.False(window1.IsActivated);
+ Assert.False(window2.IsActivated);
+ }
}
}