成都网站建设设计

将想法与焦点和您一起共享

如何用WPF代码实现窗体亚克力效果

这篇文章主要介绍“如何用WPF代码实现窗体亚克力效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何用WPF代码实现窗体亚克力效果”文章能帮助大家解决问题。

我们提供的服务有:做网站、成都网站建设、微信公众号开发、网站优化、网站认证、红古ssl等。为上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的红古网站制作公司

WPF 窗体设置亚克力效果

框架使用大于等于.NET40

Visual Studio 2022

项目使用 MIT 开源许可协议。

WindowAcrylicBlur 设置亚克力颜色。

Opacity 设置透明度。

实现代码

1) 准备WindowAcrylicBlur.cs如下:

using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using Microsoft.Win32;
using Microsoft.Windows.Shell;

namespace WPFDevelopers.Controls
{
    internal enum AccentState
    {
        ACCENT_DISABLED = 0,
        ACCENT_ENABLE_GRADIENT = 1,
        ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
        ACCENT_ENABLE_BLURBEHIND = 3,
        ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
        ACCENT_INVALID_STATE = 5
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct AccentPolicy
    {
        public AccentState AccentState;
        public uint AccentFlags;
        public uint GradientColor;
        public uint AnimationId;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct WindowCompositionAttributeData
    {
        public WindowCompositionAttribute Attribute;
        public IntPtr Data;
        public int SizeOfData;
    }

    internal enum WindowCompositionAttribute
    {
        // ...
        WCA_ACCENT_POLICY = 19
        // ...
    }

    internal class WindowOldConfig
    {
        public bool AllowsTransparency;
        public Brush Background;
        public WindowChrome WindowChrome;
        public WindowStyle WindowStyle = WindowStyle.SingleBorderWindow;
    }


    internal class WindowOSHelper
    {
        public static Version GetWindowOSVersion()
        {
            var regKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion");

            int major;
            int minor;
            int build;
            int revision;
            try
            {
                var str = regKey.GetValue("CurrentMajorVersionNumber")?.ToString();
                int.TryParse(str, out major);

                str = regKey.GetValue("CurrentMinorVersionNumber")?.ToString();
                int.TryParse(str, out minor);

                str = regKey.GetValue("CurrentBuildNumber")?.ToString();
                int.TryParse(str, out build);

                str = regKey.GetValue("BaseBuildRevisionNumber")?.ToString();
                int.TryParse(str, out revision);

                return new Version(major, minor, build, revision);
            }
            catch (Exception)
            {
                return new Version(0, 0, 0, 0);
            }
            finally
            {
                regKey.Close();
            }
        }
    }


    public class WindowAcrylicBlur : Freezable
    {
        private static readonly Color _BackgtoundColor = Color.FromArgb(0x01, 0, 0, 0); //设置透明色 防止穿透

        [DllImport("user32.dll")]
        internal static extern int SetWindowCompositionAttribute(IntPtr hwnd, ref WindowCompositionAttributeData data);

        private static bool EnableAcrylicBlur(Window window, Color color, double opacity, bool enable)
        {
            if (window == null)
                return false;

            AccentState accentState;
            var vOsVersion = WindowOSHelper.GetWindowOSVersion();
            if (vOsVersion > new Version(10, 0, 17763)) //1809
                accentState = enable ? AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND : AccentState.ACCENT_DISABLED;
            else if (vOsVersion > new Version(10, 0))
                accentState = enable ? AccentState.ACCENT_ENABLE_BLURBEHIND : AccentState.ACCENT_DISABLED;
            else
                accentState = AccentState.ACCENT_DISABLED;

            if (opacity > 1)
                opacity = 1;

            var windowHelper = new WindowInteropHelper(window);

            var accent = new AccentPolicy();

            var opacityIn = (uint) (255 * opacity);

            accent.AccentState = accentState;

            if (enable)
            {
                var blurColor = (uint) ((color.R << 0) | (color.G << 8) | (color.B << 16) | (color.A << 24));
                var blurColorIn = blurColor;
                if (opacityIn > 0)
                    blurColorIn = (opacityIn << 24) | (blurColor & 0xFFFFFF);
                else if (opacityIn == 0 && color.A == 0)
                    blurColorIn = (0x01 << 24) | (blurColor & 0xFFFFFF);

                if (accent.GradientColor == blurColorIn)
                    return true;

                accent.GradientColor = blurColorIn;
            }

            var accentStructSize = Marshal.SizeOf(accent);

            var accentPtr = Marshal.AllocHGlobal(accentStructSize);
            Marshal.StructureToPtr(accent, accentPtr, false);

            var data = new WindowCompositionAttributeData();
            data.Attribute = WindowCompositionAttribute.WCA_ACCENT_POLICY;
            data.SizeOfData = accentStructSize;
            data.Data = accentPtr;

            SetWindowCompositionAttribute(windowHelper.Handle, ref data);

            Marshal.FreeHGlobal(accentPtr);

            return true;
        }

        private static void Window_Initialized(object sender, EventArgs e)
        {
            if (!(sender is Window window))
                return;

            var config = new WindowOldConfig
            {
                WindowStyle = window.WindowStyle,
                AllowsTransparency = window.AllowsTransparency,
                Background = window.Background
            };

            var vWindowChrome = WindowChrome.GetWindowChrome(window);
            if (vWindowChrome == null)
            {
                window.WindowStyle = WindowStyle.None; //一定要将窗口的背景色改为透明才行
                window.AllowsTransparency = true; //一定要将窗口的背景色改为透明才行
                window.Background = new SolidColorBrush(_BackgtoundColor); //一定要将窗口的背景色改为透明才行
            }
            else
            {
                config.WindowChrome = new WindowChrome
                {
                    GlassFrameThickness = vWindowChrome.GlassFrameThickness
                };
                window.Background = Brushes.Transparent; //一定要将窗口的背景色改为透明才行
                var vGlassFrameThickness = vWindowChrome.GlassFrameThickness;
                vWindowChrome.GlassFrameThickness = new Thickness(0, vGlassFrameThickness.Top, 0, 0);
            }

            SetWindowOldConfig(window, config);

            window.Initialized -= Window_Initialized;
        }

        private static void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (!(sender is Window window))
                return;

            var vBlur = GetWindowAcrylicBlur(window);
            if (vBlur != null)
                EnableAcrylicBlur(window, vBlur.BlurColor, vBlur.Opacity, true);

            window.Loaded -= Window_Loaded;
        }


        protected override Freezable CreateInstanceCore()
        {
            throw new NotImplementedException();
        }

        protected override void OnChanged()
        {
            base.OnChanged();
        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
        }

        #region 开启Win11风格

        public static WindowAcrylicBlur GetWindowAcrylicBlur(DependencyObject obj)
        {
            return (WindowAcrylicBlur) obj.GetValue(WindowAcrylicBlurProperty);
        }

        public static void SetWindowAcrylicBlur(DependencyObject obj, WindowAcrylicBlur value)
        {
            obj.SetValue(WindowAcrylicBlurProperty, value);
        }

        public static readonly DependencyProperty WindowAcrylicBlurProperty =
            DependencyProperty.RegisterAttached("WindowAcrylicBlur", typeof(WindowAcrylicBlur),
                typeof(WindowAcrylicBlur),
                new PropertyMetadata(default(WindowAcrylicBlur), OnWindowAcryBlurPropertyChangedCallBack));

        private static void OnWindowAcryBlurPropertyChangedCallBack(DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            if (!(d is Window window))
                return;

            if (e.OldValue == null && e.NewValue == null)
                return;

            if (e.OldValue == null && e.NewValue != null)
            {
                window.Initialized += Window_Initialized;
                window.Loaded += Window_Loaded;
            }

            if (e.OldValue != null && e.NewValue == null)
            {
                var vConfig = GetWindowOldConfig(d);
                if (vConfig != null)
                {
                    window.WindowStyle = vConfig.WindowStyle;
                    window.AllowsTransparency = vConfig.AllowsTransparency;
                    window.Background = vConfig.Background;

                    if (vConfig.WindowChrome != null)
                    {
                        var vWindowChrome = WindowChrome.GetWindowChrome(window);
                        if (vWindowChrome != null)
                            vWindowChrome.GlassFrameThickness = vConfig.WindowChrome.GlassFrameThickness;
                    }
                }
            }

            if (e.OldValue == e.NewValue)
            {
                if (!window.IsLoaded)
                    return;

                var vBlur = e.NewValue as WindowAcrylicBlur;
                if (vBlur == null)
                    return;

                EnableAcrylicBlur(window, vBlur.BlurColor, vBlur.Opacity, true);
            }
        }

        #endregion


        #region 内部设置

        private static WindowOldConfig GetWindowOldConfig(DependencyObject obj)
        {
            return (WindowOldConfig) obj.GetValue(WindowOldConfigProperty);
        }

        private static void SetWindowOldConfig(DependencyObject obj, WindowOldConfig value)
        {
            obj.SetValue(WindowOldConfigProperty, value);
        }

        // Using a DependencyProperty as the backing store for WindowOldConfig.  This enables animation, styling, binding, etc...
        private static readonly DependencyProperty WindowOldConfigProperty =
            DependencyProperty.RegisterAttached("WindowOldConfig", typeof(WindowOldConfig), typeof(WindowAcrylicBlur),
                new PropertyMetadata(default(WindowOldConfig)));

        #endregion

        #region

        public Color BlurColor
        {
            get => (Color) GetValue(BlurColorProperty);
            set => SetValue(BlurColorProperty, value);
        }

        // Using a DependencyProperty as the backing store for BlurColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BlurColorProperty =
            DependencyProperty.Register("BlurColor", typeof(Color), typeof(WindowAcrylicBlur),
                new PropertyMetadata(default(Color)));

        public double Opacity
        {
            get => (double) GetValue(OpacityProperty);
            set => SetValue(OpacityProperty, value);
        }

        // Using a DependencyProperty as the backing store for Opacity.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OpacityProperty =
            DependencyProperty.Register("Opacity", typeof(double), typeof(WindowAcrylicBlur),
                new PropertyMetadata(default(double)));

        #endregion
    }
}

2) 使用AcrylicBlurWindowExample.xaml如下:


    
        
    
    
        
    
    
        
            
            
        
        
            
                
            
        
        
            
            
            
            
            
                
                    忘记密码
                
                
                    注册账号
                
            
        

    

3) 使用AcrylicBlurWindowExample.xaml.cs如下:

using System.Windows;
using System.Windows.Input;
using WPFDevelopers.Samples.Helpers;

namespace WPFDevelopers.Samples.ExampleViews
{
    /// 
    /// AcrylicBlurWindowExample.xaml 的交互逻辑
    /// 
    public partial class AcrylicBlurWindowExample : Window
    {
        public AcrylicBlurWindowExample()
        {
            InitializeComponent();
        }
        public ICommand CloseCommand => new RelayCommand(obj =>
        {
           Close();
        });
    }
}

实现效果

如何用WPF代码实现窗体亚克力效果

关于“如何用WPF代码实现窗体亚克力效果”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注创新互联行业资讯频道,小编每天都会为大家更新不同的知识点。


文章标题:如何用WPF代码实现窗体亚克力效果
本文路径:http://chengdu.cdxwcx.cn/article/jhgieo.html