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

如何重写Windows窗口默认最小化按钮逻辑以添加window.Hide()?

重写窗口最小化按钮逻辑,实现最小化时隐藏窗口

可以通过拦截窗口状态变更事件或平台级消息处理,实现点击最小化按钮时直接调用window.Hide()的需求,以下是适配你现有ViewModel的具体方案:

方案一:监听窗口StateChanged事件(跨平台通用)

这种方式无需平台特定代码,适合MAUI跨场景使用:

  1. 绑定窗口状态变更事件
    在项目初始化时(比如App.xaml.cs的OnStart方法),给主窗口绑定StateChanged事件:
protected override void OnStart()
{
    var mainWindow = Application.Current.MainPage?.Window;
    if (mainWindow != null)
    {
        mainWindow.StateChanged += HandleWindowStateChanged;
    }
}
  1. 实现事件处理逻辑
    在事件方法中判断窗口是否进入最小化状态,执行隐藏操作并同步ViewModel状态:
private void HandleWindowStateChanged(object sender, EventArgs e)
{
    var window = sender as Window;
    if (window?.WindowState != WindowState.Minimized) return;

    window.Hide();
    // 同步更新ViewModel的IsWindowVisible
    var viewModel = Application.Current.MainPage.BindingContext as YourViewModelClass;
    viewModel?.SetWindowVisible(false);
}
  1. ViewModel补充状态同步方法
    为了让ViewModel的状态和窗口实际状态一致,在你的ViewModel中添加一个方法:
public void SetWindowVisible(bool isVisible)
{
    IsWindowVisible = isVisible;
    // 如果你实现了INotifyPropertyChanged,记得触发属性变更通知
    OnPropertyChanged(nameof(IsWindowVisible));
}

方案二:Windows平台拦截最小化消息(无视觉闪烁)

如果不想看到窗口先最小化再隐藏的闪烁效果,可以通过Windows平台的消息钩子直接拦截最小化指令:

在Platforms/Windows/App.xaml.cs中修改OnLaunched方法,并添加消息处理逻辑:

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    base.OnLaunched(args);

    var mauiWindow = Application.Current.Windows[0];
    var winUiWindow = mauiWindow.Handler.PlatformView as Microsoft.UI.Xaml.Window;
    var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(winUiWindow);
    MinimizeHook.SetHook(hwnd);
}

private class MinimizeHook
{
    private const int WM_SYSCOMMAND = 0x0112;
    private const int SC_MINIMIZE = 0xF020;

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    private static IntPtr _prevWndProc;

    public static void SetHook(IntPtr hWnd)
    {
        _prevWndProc = SetWindowLongPtr(hWnd, -4, (IntPtr)WndProc);
    }

    private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
    {
        if (msg == WM_SYSCOMMAND && wParam.ToInt32() == SC_MINIMIZE)
        {
            // 直接执行隐藏逻辑,跳过默认最小化
            var window = Application.Current.MainPage.Window;
            window.Hide();
            var viewModel = Application.Current.MainPage.BindingContext as YourViewModelClass;
            viewModel?.SetWindowVisible(false);
            return IntPtr.Zero;
        }
        return CallWindowProc(_prevWndProc, hWnd, msg, wParam, lParam);
    }
}

结合你现有代码

你已经实现的OnShowHideWindow方法可以继续保留,用于手动触发窗口的显示/隐藏,上述方案会自动处理最小化按钮的点击事件,确保两种操作的状态保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:45:07