You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将MAUI窗口SizeChanged事件关联至页面以适配布局?

解决方案:将MAUI窗口SizeChanged事件关联到页面并实现布局适配

针对你的需求,这里提供几种实用方案,帮你把窗口尺寸变化事件关联到单个页面,实现不同屏幕尺寸下的布局切换:

方案1:利用页面自身的SizeChanged事件(跨平台通用)

MAUI的ContentPage本身自带SizeChanged事件,当窗口尺寸调整时,页面尺寸会同步变化,该事件会自动触发。这是最简单的跨平台方案,无需针对Windows写原生代码:

XAML代码

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="YourApp.MainPage"
             SizeChanged="OnPageSizeChanged">
    <!-- 定义两种布局 -->
    <Grid x:Name="MainContainer">
        <!-- 宽屏网格布局 -->
        <Grid x:Name="FullGrid" IsVisible="True">
            <!-- 网格内容 -->
        </Grid>
        <!-- 小屏卡片布局 -->
        <StackLayout x:Name="CardLayout" IsVisible="False">
            <!-- 卡片内容 -->
        </StackLayout>
    </Grid>
</ContentPage>

后台代码

private void OnPageSizeChanged(object sender, EventArgs e)
{
    // 获取当前页面尺寸(对应窗口尺寸)
    var currentSize = this.Size;
    // 根据宽度阈值切换布局
    AdjustLayout(currentSize.Width);
}

private void AdjustLayout(double windowWidth)
{
    const double wideScreenThreshold = 1000;
    FullGrid.IsVisible = windowWidth > wideScreenThreshold;
    CardLayout.IsVisible = windowWidth <= wideScreenThreshold;
}

方案2:通过消息中心传递尺寸变化(适合MVVM架构)

如果你的项目采用MVVM模式,可使用CommunityToolkit.Mvvm的WeakReferenceMessenger(比旧版MessagingCenter更安全,避免内存泄漏),在应用级事件中发送尺寸消息,页面订阅后更新布局:

1. 定义消息类

using CommunityToolkit.Mvvm.Messaging;
using Microsoft.Maui.Graphics;

public class WindowResizedMessage : ValueChangedMessage<Size>
{
    public WindowResizedMessage(Size value) : base(value) { }
}

2. 修改应用级SizeChanged事件发送消息

#if WINDOWS
static void OnSizeChanged(object sender, Microsoft.UI.Xaml.WindowSizeChangedEventArgs args)
{
    var newWindowSize = new Size(args.Size.Width, args.Size.Height);
    WeakReferenceMessenger.Default.Send(new WindowResizedMessage(newWindowSize));
}
#endif

3. 页面订阅消息并调整布局

using CommunityToolkit.Mvvm.Messaging;

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
        // 订阅窗口尺寸变化消息
        WeakReferenceMessenger.Default.Register<WindowResizedMessage>(this, (_, message) =>
        {
            var windowSize = message.Value;
            AdjustLayout(windowSize.Width);
        });
    }

    private void AdjustLayout(double windowWidth)
    {
        const double wideScreenThreshold = 1000;
        FullGrid.IsVisible = windowWidth > wideScreenThreshold;
        CardLayout.IsVisible = windowWidth <= wideScreenThreshold;
    }

    // 页面销毁时取消订阅,避免内存泄漏
    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        WeakReferenceMessenger.Default.Unregister<WindowResizedMessage>(this);
    }
}

方案3:直接在页面绑定Windows原生窗口事件

如果你需要直接获取Windows原生窗口的尺寸信息,可在页面中直接绑定原生窗口的SizeChanged事件:

#if WINDOWS
protected override void OnAppearing()
{
    base.OnAppearing();
    // 获取Windows原生窗口实例
    var nativeWindow = Microsoft.Maui.Controls.Window.Current.Handler.PlatformView as Microsoft.UI.Xaml.Window;
    nativeWindow.SizeChanged += OnNativeWindowSizeChanged;
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    var nativeWindow = Microsoft.Maui.Controls.Window.Current.Handler.PlatformView as Microsoft.UI.Xaml.Window;
    nativeWindow.SizeChanged -= OnNativeWindowSizeChanged;
}

private void OnNativeWindowSizeChanged(object sender, Microsoft.UI.Xaml.WindowSizeChangedEventArgs args)
{
    var windowWidth = args.Size.Width;
    AdjustLayout(windowWidth);
}
#endif

private void AdjustLayout(double windowWidth)
{
    const double wideScreenThreshold = 1000;
    FullGrid.IsVisible = windowWidth > wideScreenThreshold;
    CardLayout.IsVisible = windowWidth <= wideScreenThreshold;
}

补充提示

  • MAUI使用独立设备像素作为尺寸单位,无需额外处理DPI适配,直接用宽度值判断即可
  • 可根据实际需求调整宽屏/小屏的阈值(比如平板可设为800)
  • 测试时可手动拖拽窗口边缘,验证布局切换是否流畅

内容的提问来源于stack exchange,提问作者MaxTheCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:48:57