WinUI3应用最大化禁用恢复按钮后,最小化重开UI下移原因排查
WinUI3应用最小化恢复后UI偏移问题解决
我开发了一个包含两个页面的WinUI 3应用,主页面设有按钮可导航至第二页。导航至第二页时,需将窗口设置为最大化状态并禁用恢复按钮,但当应用被最小化后重新打开,UI会出现向下偏移的问题。
相关代码
主窗口代码
XAML
<Window x:Class="App1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="App1"> <Window.SystemBackdrop> <MicaBackdrop /> </Window.SystemBackdrop> <Frame x:Name="ContentFrame" /> </Window>
C#
using Microsoft.UI.Windowing; using Microsoft.UI.Xaml; namespace App1 { public sealed partial class MainWindow : Window { public MainWindow() { InitializeComponent(); ContentFrame.Navigated += ContentFrame_Navigated; ContentFrame.Navigate(typeof(MainPage), this); Activated += MainWindow_Activated; } private void MainWindow_Activated(object sender, WindowActivatedEventArgs args) { if (args.WindowActivationState != WindowActivationState.Deactivated) { ContentFrame.UpdateLayout(); this.UpdateLayout(); } } private void ContentFrame_Navigated(object sender, Microsoft.UI.Xaml.Navigation.NavigationEventArgs e) { var appWindow = GetAppWindowForCurrentWindow(); if (appWindow != null && appWindow.Presenter is OverlappedPresenter presenter) { if (e.SourcePageType == typeof(SecondPage)) { presenter.IsMaximizable = false; presenter.IsResizable = false; presenter.Maximize(); } else { presenter.IsMaximizable = true; presenter.IsResizable = true; if (presenter.State == OverlappedPresenterState.Maximized) { presenter.Restore(); } } } } public void NavigateToSecondPage() { ContentFrame.Navigate(typeof(SecondPage)); } public AppWindow? GetAppWindowForCurrentWindow() { var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this); var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd); return AppWindow.GetFromWindowId(windowId); } } }
第一页代码
XAML
<Page x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Button x:Name="OpenSecondPageBtn" Content="Open Second Screen" Click="OpenSecondPageBtn_Click" Width="200" /> </Page>
C#
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Navigation; namespace App1 { public sealed partial class MainPage : Page { private MainWindow? _mainWindow; public MainPage() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); if (e.Parameter is MainWindow mainWindow) { _mainWindow = mainWindow; } } private void OpenSecondPageBtn_Click(object sender, RoutedEventArgs e) { _mainWindow?.NavigateToSecondPage(); } } }
第二页代码
XAML
<Page x:Class="App1.SecondPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="20"> <TextBlock Text="Second Screen" FontSize="32" FontWeight="Bold" HorizontalAlignment="Center" /> <TextBlock Text="Window is maximized and cannot be resized" FontSize="16" HorizontalAlignment="Center" Foreground="{ThemeResource SystemFillColorAttentionBrush}" /> <Button x:Name="BackBtn" Content="Back to Main Screen" Click="BackBtn_Click" Width="200" HorizontalAlignment="Center" Margin="0,20,0,0" /> </StackPanel> </Page>
C#
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; namespace App1 { public sealed partial class SecondPage : Page { public SecondPage() { InitializeComponent(); } private void BackBtn_Click(object sender, RoutedEventArgs e) { if (Frame.CanGoBack) { Frame.GoBack(); } } } }
问题截图
- 问题发生前:

- 应用最小化后重新打开:

问题原因及解决说明
原因
原代码先执行Maximize()再禁用窗口最大化和调整大小功能,导致WinUI窗口布局计算异常。窗口从最小化恢复时,系统未正确重新计算工作区与UI元素的位置关系,引发偏移。
解决要点
- 调整窗口状态设置顺序:先禁用窗口最大化和调整大小属性,再调用
Maximize(),确保状态变更时布局逻辑正确触发。 - 监听窗口激活事件:在窗口从最小化恢复激活时,强制刷新UI布局,重新计算元素位置。
内容的提问来源于stack exchange,提问作者AkritiCodes




