先看看效果图
目前网上找到了2种实现方式,一种是 .NET Framework4.5及以后有自带的 WindowChrome 效果,一种是 WindowsAPI dwmapi.dll ,但这两种在win10下面都会失效。win10如何实现在下一篇讲。
1.WindowChrome 效果设置较为简单,代码如下。WindowChrome更多用法可以查阅官方文档:https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.shell.windowchrome?view=netframework-4.7.2
<Window x:Class="WpfApp1.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="Window1" Height="300" Width="300" Background="Transparent" WindowStartupLocation="CenterScreen"> <WindowChrome.WindowChrome> <WindowChrome GlassFrameThickness="-1"/> </WindowChrome.WindowChrome> <Grid> <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> <TextBlock FontSize="40" TextAlignment="Center"> Hello Wolrd </TextBlock> <TextBlock FontSize="12" TextAlignment="Center" Margin="0,30,0,0">使用 WindowChrome 实现模糊透明</TextBlock> </StackPanel> </Grid> </Window>
2.调用 dwmapi.dll API
页面代码:
<Window x:Class="WpfApp1.Window2" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="Window2" Height="300" Width="300" WindowStartupLocation="CenterScreen"> <Grid> <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center"> <TextBlock FontSize="40" TextAlignment="Center"> Hello Wolrd </TextBlock> <TextBlock FontSize="12" TextAlignment="Center" Margin="0,30,0,0">使用 Windows 的 dwmapi 实现模糊透明</TextBlock> </StackPanel> </Grid> </Window>
后端代码:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace WpfApp1 { /// <summary> /// Window2.xaml 的交互逻辑 /// </summary> public partial class Window2 : Window { public Window2() { InitializeComponent(); } [StructLayout(LayoutKind.Sequential)] private struct MARGINS { public MARGINS(Thickness t) { Left = (int)t.Left; Right = (int)t.Right; Top = (int)t.Top; Bottom = (int)t.Bottom; } public int Left; public int Right; public int Top; public int Bottom; } [DllImport("dwmapi.dll", PreserveSig = false)] private static extern void DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMarInset); [DllImport("dwmapi.dll", PreserveSig = false)] private static extern bool DwmIsCompositionEnabled(); /// <summary> /// win7 /// </summary> /// <param name="window"></param> /// <param name="margin"></param> /// <returns></returns> public static bool ExtendGlassFrame(Window window) { if (!DwmIsCompositionEnabled()) return false; IntPtr hwnd = new WindowInteropHelper(window).Handle; if (hwnd == IntPtr.Zero) throw new InvalidOperationException("The Window must be shown before extending glass."); // 将WPF和Win32透视图的背景设置为透明 window.Background = Brushes.Transparent; HwndSource.FromHwnd(hwnd).CompositionTarget.BackgroundColor = Colors.Transparent; MARGINS margins = new MARGINS(new Thickness(-1)); DwmExtendFrameIntoClientArea(hwnd, ref margins); return true; } protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); ExtendGlassFrame(this); } } }
这两种都能实现透明模糊效果(win7下),但都各自有各自的特点,WindowChrome 的窗口内容都需要自行设置,细心看两个窗口就会发现WindowChrome 的窗口标题都没了,标题高度,边距,调整窗口大小的作用范围等,什么都可以自定义,自我感觉比较难调(可能只是因为我菜),比较适合做自定义窗口,标题栏自定义,标题栏上面还可以加其他按钮,可以隐藏系统标题栏上面的按钮,还有个特点是程序启动时立即生效,dwmapi.dll 会有一个加载的延迟,使用 dwmapi.dll 则窗口内容标题等都是保留原始窗口的内容。