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

目录

(提示!!!.Net 8中该方法已失效)

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

如果去掉默认的标题栏,自己画一个,可能会出现问题,也比较麻烦。

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

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

在Win10和Win11中都可以正常用。

修改默认颜色

找到Platforms/Windows/App.xaml

<maui:MauiWinUIApplication
    x:Class="MauiApp1.WinUI.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:maui="using:Microsoft.Maui"
    xmlns:local="using:MauiApp1.WinUI">
    <Application.Resources>
        <ResourceDictionary>
            <SolidColorBrush x:Key="WindowCaptionBackground">#fff</SolidColorBrush>
            <SolidColorBrush x:Key="WindowCaptionBackgroundDisabled">#fff</SolidColorBrush>
            <SolidColorBrush x:Key="WindowCaptionForeground">#000</SolidColorBrush>
            <SolidColorBrush x:Key="WindowCaptionForegroundDisabled">#000</SolidColorBrush>
        </ResourceDictionary>
    </Application.Resources>
</maui:MauiWinUIApplication>

修改运行时颜色

  • 安装NuGet包

    NuGet包中搜索 PInvoke.User32 ,安装它

    image

    ###特别提示

    项目文件中请务必按照下面这样写,否则打包的时候其他平台也会将PInvoke.User32这个包打进去,实际上是完全无用的,它只适用于Windows。

     ```
     <PackageReference Include="PInvoke.User32" Version="0.7.124" Condition="$(TargetFramework.Contains('-windows')) == true" />
     ```
    
  • 添加修改标题栏颜色的类

    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;
      		}
      	}
      }
    
    
  • 调用

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

效果图

image

posted @ 2023-04-26 17:25  Yu-Core  阅读(559)  评论(0)    收藏  举报