Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Screenbox/Pages/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
xmlns:strings="using:Screenbox.Strings"
xmlns:triggers="using:Screenbox.Triggers"
muxc:BackdropMaterial.ApplyToRootOrPageBackground="True"
Loaded="MainPage_Loaded"
mc:Ignorable="d">
Expand Down Expand Up @@ -412,9 +413,10 @@

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WindowActivationStates">
<VisualState x:Name="Activated" />

<VisualState x:Name="Deactivated">
<VisualState.StateTriggers>
<triggers:WindowActivationModeTrigger ActivationMode="Deactivated" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="AppTitleText.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" />
<Setter Target="NavView.IsBackEnabled" Value="False" />
Expand Down
18 changes: 0 additions & 18 deletions Screenbox/Pages/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ public MainPage()
// For example, when the app moves to a screen with a different DPI.
coreTitleBar.LayoutMetricsChanged += CoreTitleBar_LayoutMetricsChanged;

// Register a handler for when the window changes focus
Window.Current.CoreWindow.Activated += CoreWindow_Activated;

NotificationView.Translation = new Vector3(0, 0, 16);

_pages = new Dictionary<string, Type>
Expand Down Expand Up @@ -81,21 +78,6 @@ private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sende
RightPaddingColumn.Width = new GridLength(Math.Max(sender.SystemOverlayLeftInset, sender.SystemOverlayRightInset));
}

/// <summary>
/// Change the <see cref="VisualState"/> depending on whether the app is active or inactive.
/// </summary>
private void CoreWindow_Activated(CoreWindow sender, WindowActivatedEventArgs args)
{
if (args.WindowActivationState == CoreWindowActivationState.Deactivated)
{
VisualStateManager.GoToState(this, "Deactivated", true);
}
else
{
VisualStateManager.GoToState(this, "Activated", true);
}
}

protected override void OnNavigatedTo(NavigationEventArgs e)
{
PlayerFrame.Navigate(typeof(PlayerPage), e.Parameter);
Expand Down
1 change: 1 addition & 0 deletions Screenbox/Screenbox.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Secrets.cs" />
<Compile Include="Services\ResourceService.cs" />
<Compile Include="Triggers\WindowActivationModeTrigger.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
Expand Down
101 changes: 101 additions & 0 deletions Screenbox/Triggers/WindowActivationModeTrigger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#nullable enable

using Windows.UI.Core;
using Windows.UI.Xaml;

namespace Screenbox.Triggers;

/// <summary>
/// Represents a declarative rule that applies visual states based on the <see cref="CoreWindow.ActivationMode"/> property.
/// </summary>
/// <remarks>
/// Use WindowActivationModeTriggers to create rules that automatically triggers a VisualState change when
/// the window is a specified activation state. When you use WindowActivationModeTriggers in your XAML markup,
/// you don't need to handle the <see cref="CoreWindow.Activated"/> event and call <see cref="VisualStateManager.GoToState"/> in your code.
/// </remarks>
/// <example>
/// This example shows how to use the <see cref="VisualState.StateTriggers"/> property with an <see cref="WindowActivationModeTrigger"/>
/// to create a declarative rule in XAML markup based on the activation state of the window.
/// <code lang="xaml">
/// &lt;Grid&gt;
/// &lt;StackPanel&gt;
/// &lt;TextBlock x:Name="FirstText"
/// Foreground="{ThemeResource TextFillColorPrimaryBrush}"
/// Text="This is a block of text. It is the 1st text block." /&gt;
/// &lt;TextBlock x:Name="LastText"
/// Foreground="{ThemeResource TextFillColorPrimaryBrush}"
/// Text="This is a block of text. It is the 2nd text block." /&gt;
/// &lt;/StackPanel&gt;
/// &lt;VisualStateManager.VisualStateGroups&gt;
/// &lt;VisualStateGroup&gt;
/// &lt;VisualState&gt;
/// &lt;VisualState.StateTriggers&gt;
/// &lt;!-- VisualState to be triggered when the activation state of the window is Deactivated. --&gt;
/// &lt;local:WindowActivationModeTrigger ActivationMode="Deactivated" /&gt;
/// &lt;/VisualState.StateTriggers&gt;
///
/// &lt;VisualState.Setters&gt;
/// &lt;Setter Target="FirstText.Foreground" Value="{ThemeResource TextFillColorDisabledBrush}" /&gt;
/// &lt;Setter Target="LastText.Opacity" Value="0.4" /&gt;
/// &lt;/VisualState.Setters&gt;
/// &lt;/VisualState&gt;
/// &lt;/VisualStateGroup&gt;
/// &lt;/VisualStateManager.VisualStateGroups&gt;
/// &lt;/Grid&gt;
/// </code>
/// </example>
[Windows.Foundation.Metadata.ContractVersion(typeof(Windows.Foundation.UniversalApiContract), 327680u)]
public sealed class WindowActivationModeTrigger : StateTriggerBase
{
private CoreWindow? _coreWindow;

/// <summary>
/// Identifies the <see cref="ActivationMode"/> dependency property.
/// </summary>
public static readonly DependencyProperty ActivationModeProperty = DependencyProperty.Register(
nameof(ActivationMode), typeof(CoreWindowActivationMode), typeof(WindowActivationModeTrigger), new PropertyMetadata(CoreWindowActivationMode.None, OnActivationModePropertyChanged));

/// <summary>
/// Gets or sets the activation mode that indicates whether the trigger should be applied.
/// </summary>
public CoreWindowActivationMode ActivationMode
{
get { return (CoreWindowActivationMode)GetValue(ActivationModeProperty); }
set { SetValue(ActivationModeProperty, value); }
}

private static void OnActivationModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is WindowActivationModeTrigger trigger)
{
trigger.UpdateActivatedEventHandler();
trigger.UpdateTrigger();
}
}

private void UpdateActivatedEventHandler()
{
_coreWindow = Window.Current?.CoreWindow;

var coreWindow = _coreWindow;
if (coreWindow != null)
{
coreWindow.Activated -= OnActivated;

if (ActivationMode is not CoreWindowActivationMode.None)
{
coreWindow.Activated += OnActivated;
}
}
}

private void OnActivated(CoreWindow sender, WindowActivatedEventArgs args)
{
UpdateTrigger();
}

private void UpdateTrigger()
{
SetActive(_coreWindow?.ActivationMode == ActivationMode);
}
}
Loading