【问题标题】:Areo Glass Effect and windowStyle set to none causes window resize to not function properlyAreo Glass Effect 和 windowStyle 设置为 none 会导致窗口调整大小无法正常工作
【发布时间】:2026-01-13 15:35:01
【问题描述】:

Areo Glass Effect 和 windowStyle 设置为 none 和 AllowTransparency 导致寡妇调整大小无法正常工作

将 Areo Glass 主题添加到我的窗口并将 WindowState 设置为 None 后,窗口无法正确调整大小。我可以随心所欲地变大,但是当缩小尺寸时,玻璃效果保持相同的宽度和高度。

例如,我单击最大化。窗口扩展为全屏大小。但是当恢复我的窗口时,我的窗口会恢复,但不会恢复玻璃效果。

我真正想要的只是模糊效果。我不在乎玻璃,但这似乎是我可以获得透明模糊的唯一方法。

我该如何解决这个问题?

xaml

    <Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" WindowStyle="None" ResizeMode="CanResizeWithGrip" Background="Transparent">
    <Border BorderThickness="1" Margin="0,35,0,0" BorderBrush="Orange">
    <Grid Background="#0CFFA500">

            <DockPanel VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="35" Background="#4effffff">
            <DockPanel.Resources>
                <Style x:Key="WindowIconStyle" TargetType="{x:Type Button}">
                    <Setter Property="FontSize" Value="16" />
                    <Setter Property="Foreground" Value="#444" />
                    <Setter Property="Height" Value="30"></Setter>
                    <Setter Property="Width" Value="30"></Setter>
                    <Setter Property="FontFamily" Value="Webdings"></Setter>
                    <Setter Property="Background" Value="#ff0000"></Setter>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type Button}">
                                <Border BorderBrush="Transparent" BorderThickness="0.5,0,0.5,0">
                                    <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="#77abff" />
                            <Setter Property="Foreground" Value="#000000" />
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type Button}">
                                        <Border BorderBrush="Black" BorderThickness="1,0,1,0">
                                            <Border.Background>
                                                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                                    <GradientStop Color="Black" Offset="1"/>
                                                    <GradientStop Color="White" Offset="0.952"/>
                                                    <GradientStop Color="Black" Offset="0"/>
                                                    <GradientStop Color="#FFF7F7F7" Offset="0.044"/>
                                                </LinearGradientBrush>
                                            </Border.Background>
                                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger  Property="IsPressed" Value="True">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type Button}">
                                        <Border BorderBrush="#444" BorderThickness="1,0,1,0">
                                            <Border.Background>
                                                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                                    <GradientStop Color="#444" Offset="1"/>
                                                    <GradientStop Color="#ffececec" Offset="0.952"/>
                                                    <GradientStop Color="#444" Offset="0"/>
                                                    <GradientStop Color="#ffececec" Offset="0.044"/>
                                                </LinearGradientBrush>
                                            </Border.Background>
                                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DockPanel.Resources>
            <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerClose" Style="{StaticResource WindowIconStyle}" Content="r" />
            <Button x:Name="btnMaximize" DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMaximize" Style="{StaticResource WindowIconStyle}"  Content="c" />
            <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMinimize" Style="{StaticResource WindowIconStyle}" Content="0" />
            <StatusBar Background="Transparent" MouseDoubleClick="TriggerMaximize" MouseMove="TriggerMoveWindow" >
                <TextBlock DockPanel.Dock="Left" x:Name="txtTitle" Text="Title" FontSize="16" Padding="10,0,0,0"/>
            </StatusBar>
        </DockPanel>
            <Border BorderThickness="0,1,0,0" Margin="0,35,0,0" BorderBrush="#f7000000">

        </Border>
    </Grid>
    </Border>
</Window>

C#

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;


namespace WpfApplication2 {

    public partial class MainWindow : Window {

        #region Constants

        private System.Windows.Window me { get; set; }
        private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
        private const int DWM_BB_ENABLE = 0x1;

        #endregion //Constants

        #region Structures
        [StructLayout(LayoutKind.Sequential)]
        private struct DWM_BLURBEHIND {
            public int dwFlags;
            public bool fEnable;
            public IntPtr hRgnBlur;
            public bool fTransitionOnMaximized;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct MARGINS {
            public int cxLeftWidth;
            public int cxRightWidth;
            public int cyTopHeight;
            public int cyBottomHeight;
        }
        #endregion //Structures

        #region APIs

        [DllImport("dwmapi.dll", PreserveSig = false)]
        private static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
        [DllImport("dwmapi.dll")]
        private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);
        [DllImport("dwmapi.dll", PreserveSig = false)]
        private static extern bool DwmIsCompositionEnabled();

        #endregion //APIs

        public MainWindow() {
            SourceInitialized += OnSourceInitialized;
            InitializeComponent();
        }

        private void OnSourceInitialized(object sender, EventArgs eventArgs) {
            me = (Window)sender;
            if (Environment.OSVersion.Version.Major >= 6) {
                var hwnd = new WindowInteropHelper(me).Handle;
                var hs = HwndSource.FromHwnd(hwnd);
                hs.CompositionTarget.BackgroundColor = System.Windows.Media.Colors.Transparent;

                hs.AddHook(new HwndSourceHook(this.WndProc));
                this.InitializeGlass(hwnd);
            }

        }

        public System.Windows.Media.Color GetAreoColor() {
            int icolor = (int)Microsoft.Win32.Registry.GetValue(@"HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", "ColorizationColor", null);
            var c = System.Drawing.Color.FromArgb(icolor);
            return System.Windows.Media.Color.FromArgb(c.A, c.R, c.G, c.B);
        }


        private static String ConverterToHex(System.Drawing.Color c) {
            return String.Format("#{0}{1}{2}", c.R.ToString("X2"), c.G.ToString("X2"), c.B.ToString("X2"));
        }

        #region Methods

        #region InitializeGlass
        public void InitializeGlass(IntPtr hwnd) {
            if (!DwmIsCompositionEnabled())
                return;

            // fill the background with glass
            var margins = new MARGINS();
            margins.cxLeftWidth = margins.cxRightWidth = margins.cyBottomHeight = margins.cyTopHeight = -1;
            DwmExtendFrameIntoClientArea(hwnd, ref margins);

            // initialize blur for the window
            DWM_BLURBEHIND bbh = new DWM_BLURBEHIND();
            bbh.fEnable = true;
            // bbh.fTransitionOnMaximized = true;

            bbh.dwFlags = DWM_BB_ENABLE;
            DwmEnableBlurBehindWindow(hwnd, ref bbh);
        }
        #endregion //InitializeGlass

        #region WndProc
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
            if (msg == WM_DWMCOMPOSITIONCHANGED) {
                this.InitializeGlass(hwnd);
                handled = false;
            }

            return IntPtr.Zero;
        }
        #endregion //WndProc

        #endregion //Methods


        private void TriggerMoveWindow(object sender, MouseEventArgs e) {
            if (e.LeftButton == MouseButtonState.Pressed) {
                if (WindowState == System.Windows.WindowState.Maximized) {
                    WindowState = System.Windows.WindowState.Normal;

                    double pct = PointToScreen(e.GetPosition(this)).X / System.Windows.SystemParameters.PrimaryScreenWidth;
                    Top = 0;
                    Left = e.GetPosition(this).X - (pct * Width);
                }

                Application.Current.MainWindow.DragMove();
            }
        }

        private void TriggerMaximize(object sender, EventArgs e) {
            if (WindowState == System.Windows.WindowState.Maximized) {
                WindowState = System.Windows.WindowState.Normal;
                btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Webdings");
                btnMaximize.Content = "c";
            } else if (WindowState == System.Windows.WindowState.Normal) {
                WindowState = System.Windows.WindowState.Maximized;
                btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Wingdings");
                btnMaximize.Content = "r";
                InvalidateVisual();
            }
        }

        private void TriggerClose(object sender, RoutedEventArgs e) {
                Close();
        }

        private void TriggerMinimize(object sender, RoutedEventArgs e) {
            WindowState = System.Windows.WindowState.Minimized;
        }
    }
}

【问题讨论】:

  • 我问错了吗?所有代码都在这里复制问题。将给予能正确回答问题的人 50 赏金。
  • 您好,我看过这个,但我不太确定出了什么问题。只是想提一下,尽管使用您的示例,模糊根本不起作用 - 相反,我得到一个纯白色块,透明度应该是(使用 Windows 8.1)
  • s_mg 此示例仅适用于 Window 7。我找不到适用于 Windows 8 的模糊。微软把它拿出来了。用 Windows 10 把它带回来,但比我上面的代码更容易。最终解决方案在初始化时检查 Windows 的版本,然后从那里开始。 blur-behind-transparent-wpf-window

标签: c# wpf xaml


【解决方案1】:

似乎AllowsTransparency == True 是这种行为的根源。因此,您可以将其删除。但是,您应该将背景画笔的不透明度设置为零:

<Window.Background>
    <SolidColorBrush Opacity="0" Color="Transparent"/>
</Window.Background>

这与将CompositionTarget.BackgroundColor 设置为透明,并使用DwmEnableBlurBehindWindow 函数将产生与设置AllowsTransparency == True 类似的结果。

但是,通过这些修改,由于边框的原因,窗口的外观不是很讨人喜欢。如果您设置ResizeMode=="NoResize",边框将消失。但是,在这种情况下,您应该自己实施调整大小。幸运的是,通过添加 Thumb 并处理 DragDelta 事件,这很容易。完整代码如下:

Xaml

 <Window x:Class="Test1.MainWindow"
    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:Test1" 
    mc:Ignorable="d"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    Title="MainWindow" Name="window" 
    Height="350" Width="525" WindowStyle="None" ResizeMode="NoResize" >
<Window.Background>
    <SolidColorBrush Opacity="0" Color="Transparent"/>
</Window.Background>

<Grid>
    <Thumb DockPanel.Dock="Bottom" DragDelta="Thumb_DragDelta" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="8" Height="8" Cursor="SizeNWSE" Background="Red" Panel.ZIndex="4"/>
    <Border BorderThickness="1" BorderBrush="Orange" Margin="0,0,0,0">
        <Grid Background="#0CFFA500">
            <DockPanel VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="35" Background="#4effffff">
                <DockPanel.Resources>
                    <Style x:Key="WindowIconStyle" TargetType="{x:Type Button}">
                        <Setter Property="FontSize" Value="16" />
                        <Setter Property="Foreground" Value="#444" />
                        <Setter Property="Height" Value="30"></Setter>
                        <Setter Property="Width" Value="30"></Setter>
                        <Setter Property="FontFamily" Value="Webdings"></Setter>
                        <Setter Property="Background" Value="#ff0000"></Setter>
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type Button}">
                                    <Border BorderBrush="Transparent" BorderThickness="0.5,0,0.5,0">
                                        <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="#77abff" />
                                <Setter Property="Foreground" Value="#000000" />
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Button}">
                                            <Border BorderBrush="Black" BorderThickness="1,0,1,0">
                                                <Border.Background>
                                                    <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                                        <GradientStop Color="Black" Offset="1"/>
                                                        <GradientStop Color="White" Offset="0.952"/>
                                                        <GradientStop Color="Black" Offset="0"/>
                                                        <GradientStop Color="#FFF7F7F7" Offset="0.044"/>
                                                    </LinearGradientBrush>
                                                </Border.Background>
                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                            </Border>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                            <Trigger  Property="IsPressed" Value="True">
                                <Setter Property="Template">
                                    <Setter.Value>
                                        <ControlTemplate TargetType="{x:Type Button}">
                                            <Border BorderBrush="#444" BorderThickness="1,0,1,0">
                                                <Border.Background>
                                                    <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                                        <GradientStop Color="#444" Offset="1"/>
                                                        <GradientStop Color="#ffececec" Offset="0.952"/>
                                                        <GradientStop Color="#444" Offset="0"/>
                                                        <GradientStop Color="#ffececec" Offset="0.044"/>
                                                    </LinearGradientBrush>
                                                </Border.Background>
                                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                                            </Border>
                                        </ControlTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </DockPanel.Resources>
                <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerClose" Style="{StaticResource WindowIconStyle}" Content="r" />
                <Button x:Name="btnMaximize" DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMaximize" Style="{StaticResource WindowIconStyle}"  Content="c" />
                <Button DockPanel.Dock="Right" VerticalAlignment="Center" HorizontalAlignment="Right" Click="TriggerMinimize" Style="{StaticResource WindowIconStyle}" Content="0" />
                <StatusBar Background="Transparent" MouseDoubleClick="TriggerMaximize" MouseMove="TriggerMoveWindow" >
                    <TextBlock DockPanel.Dock="Left" x:Name="txtTitle" Text="Title" FontSize="16" Padding="10,0,0,0"/>
                </StatusBar>
            </DockPanel>
            <Border BorderThickness="0,1,0,0" Margin="0,35,0,0" BorderBrush="#f7000000">

            </Border>
        </Grid>
    </Border>
</Grid>
</Window>

CS 代码

public partial class MainWindow : Window
{ 
    private const int WM_DWMCOMPOSITIONCHANGED = 0x031E;
    private const int DWM_BB_ENABLE = 0x1; 

    [StructLayout(LayoutKind.Sequential)]
    private struct DWM_BLURBEHIND
    {
        public int dwFlags;
        public bool fEnable;
        public IntPtr hRgnBlur;
        public bool fTransitionOnMaximized;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    } 

    [DllImport("dwmapi.dll", PreserveSig = false)]
    private static extern void DwmEnableBlurBehindWindow(IntPtr hwnd, ref DWM_BLURBEHIND blurBehind);
    [DllImport("dwmapi.dll")]
    private static extern int DwmExtendFrameIntoClientArea(IntPtr hWnd, ref MARGINS pMargins);
    [DllImport("dwmapi.dll", PreserveSig = false)]
    private static extern bool DwmIsCompositionEnabled();

    public MainWindow()
    { 
        InitializeComponent();
        SourceInitialized += OnSourceInitialized; 
    } 

    private void OnSourceInitialized(object sender, EventArgs eventArgs)
    {
        var hwnd = new WindowInteropHelper(this).Handle;
        var hs = HwndSource.FromHwnd(hwnd);
        hs.CompositionTarget.BackgroundColor = System.Windows.Media.Colors.Transparent;

        var margins = new MARGINS();
        margins.cxLeftWidth = margins.cxRightWidth = margins.cyTopHeight = margins.cyBottomHeight = -1;

        DwmExtendFrameIntoClientArea(hwnd, ref margins);

        DWM_BLURBEHIND bbh = new DWM_BLURBEHIND();
        bbh.fEnable = true;
        bbh.dwFlags = DWM_BB_ENABLE;
        DwmEnableBlurBehindWindow(hwnd, ref bbh);
    }

    private void TriggerMinimize(object sender, RoutedEventArgs e)
    {
        WindowState = System.Windows.WindowState.Minimized;
    }

    private void TriggerMoveWindow(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (WindowState == System.Windows.WindowState.Maximized)
            {
                WindowState = System.Windows.WindowState.Normal; 
                double pct = PointToScreen(e.GetPosition(this)).X / System.Windows.SystemParameters.PrimaryScreenWidth;
                Top = 0;
                Left = e.GetPosition(this).X - (pct * Width);
            }

            Application.Current.MainWindow.DragMove();
        }
    }

    private void TriggerMaximize(object sender, EventArgs e)
    {
        if (WindowState == System.Windows.WindowState.Maximized)
        {
            WindowState = System.Windows.WindowState.Normal;
            btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Webdings");
            btnMaximize.Content = "c";
        }
        else if (WindowState == System.Windows.WindowState.Normal)
        {
            WindowState = System.Windows.WindowState.Maximized;
            btnMaximize.FontFamily = new System.Windows.Media.FontFamily("Wingdings");
            btnMaximize.Content = "r";
            InvalidateVisual();
        }
    }

    private void TriggerClose(object sender, RoutedEventArgs e)
    {
        Close();
    }

    private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
        this.Height += e.VerticalChange;
        this.Width += e.HorizontalChange;
    }
}

你可以看到结果:

【讨论】: