【MAUI Blazor踩坑日记】3.Windows标题栏自定义颜色,运行时改变颜色

发布时间 2023-04-26 17:32:31作者: Yu-Core

前言

MAUI中Windows默认的标题栏颜色是灰色的,有一点丑。

对于想要自定义颜色,官方没有提供接口。找过了很多资料,也用过很多办法,始终不能完美的解决这个问题,大多数只是类似于配置的修改,不能在运行时修改颜色。

直到看到一位大佬的文章https://www.dongchuanmin.com/net/2955.html ,终于有了眉目。

正文

  1. 安装NuGet包 PInvoke.User32

image

  1. Platforms/Windows文件夹下添加WindowsTitleBar.cs
using Microsoft.Maui.Platform;
using PInvoke;
using WinRT.Interop;
using static PInvoke.User32;

namespace MauiApp1
{
# nullable disable
    public static class WindowsTitleBar
    {
        private static Microsoft.UI.Xaml.Window GetActiveNativeWindow() =>
        (Microsoft.UI.Xaml.Window)Application.Current.Windows.FirstOrDefault()?.Handler?.PlatformView;

        public static void SetColorForWindows(Color backgroundColor,Color foregroundColor)
        {
            var res = Microsoft.UI.Xaml.Application.Current.Resources;
            res["WindowCaptionBackground"] = backgroundColor.ToWindowsColor();
            res["WindowCaptionBackgroundDisabled"] = backgroundColor.ToWindowsColor();
            res["WindowCaptionForeground"] = foregroundColor.ToWindowsColor();
            res["WindowCaptionForegroundDisabled"] = foregroundColor.ToWindowsColor();
            TriggertTitleBarRepaint();
        }

        private static bool TriggertTitleBarRepaint()
        {
#if WINDOWS
            var nativeWindow = GetActiveNativeWindow();
            if (nativeWindow is null) 
            { 
                return default; 
            }

            var hWnd = WindowNative.GetWindowHandle(nativeWindow);
            var activeWindow = User32.GetActiveWindow();
            if (hWnd == activeWindow)
            {
                User32.PostMessage(hWnd, WindowMessage.WM_ACTIVATE, new IntPtr((int)0x00), IntPtr.Zero);
                User32.PostMessage(hWnd, WindowMessage.WM_ACTIVATE, new IntPtr((int)0x01), IntPtr.Zero);
            }
            else
            {
                User32.PostMessage(hWnd, WindowMessage.WM_ACTIVATE, new IntPtr((int)0x01), IntPtr.Zero);
                User32.PostMessage(hWnd, WindowMessage.WM_ACTIVATE, new IntPtr((int)0x00), IntPtr.Zero);
            }

#endif
            return true;
        }
    }
}

  1. 使用
#if WINDOWS
	var backgroundColor = Colors.White;
	var foreColor = Colors.Black;
	WindowsTitleBar.SetColorForWindows(backgroundColor, foreColor);
#endif

效果图

image