wpF 窗体设置亚克力效果
框架使用大于等于.NET40
。
Visual Studio 2022
。
项目使用 MIT 开源许可协议。
WindowAcrylicBlur
设置亚克力颜色。
Opacity
设置透明度。
实现代码
1) 准备WindowAcrylicBlur.cs如下:
usingSystem; usingSystem.Runtime.InteropServices; usingSystem.Windows; usingSystem.Windows.Interop; usingSystem.Windows.Media; usingMicrosoft.Win32; usingMicrosoft.Windows.Shell; namespaceWPFDevelopers.Controls { internalenuMACcentState { 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)] internalstructAccentPolicy { publicAccentStateAccentState; publicuintAccentFlags; publicuintGradientColor; publicuintAnimationId; } [StructLayout(LayoutKind.Sequential)] internalstructWindowCompositionAttributeData { publicWindowCompositionAttributeAttribute; publicIntPtrData; publicintSizeOfData; } internalenumWindowCompositionAttribute { //... WCA_ACCENT_POLICY=19 //... } internalclassWindowOldConfig { publicboolAllowsTransparency; publicBrushBackground; publicWindowChromeWindowChrome; publicWindowStyleWindowStyle=WindowStyle.SingleBorderWindow; } internalclassWindowOSHelper { publicstaticVersionGetWindowOSVersion() { varregKey=Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\WindowsNT\CurrentVersion"); intmajor; intminor; intbuild; intrevision; try { varstr=regKey.GetValue("CurrentMajorVersionNumber")?.ToString(); int.TryParse(str,outmajor); str=regKey.GetValue("CurrentMinorVersionNumber")?.ToString(); int.TryParse(str,outminor); str=regKey.GetValue("CurrentBuildNumber")?.ToString(); int.TryParse(str,outbuild); str=regKey.GetValue("BaseBuildRevisionNumber")?.ToString(); int.TryParse(str,outrevision); returnnewVersion(major,minor,build,revision); } catch(Exception) { returnnewVersion(0,0,0,0); } finally { regKey.Close(); } } } publicclassWindowAcrylicBlur:Freezable { privatestaticreadonlyColor_BackgtoundColor=Color.FromArgb(0x01,0,0,0);//设置透明色防止穿透 [DllImport("user32.dll")] internalstaticexternintSetWindowCompositionAttribute(IntPtrhwnd,refWindowCompositionAttributeDatadata); privatestaticboolEnableAcrylicBlur(Windowwindow,Colorcolor,doubleopacity,boolenable) { if(window==null) returnfalse; AccentStateaccentState; varvOsVersion=WindowOSHelper.GetWindowOSVersion(); if(vOsVersion>newVersion(10,0,17763))//1809 accentState=enablewww.devze.com?AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND:AccentState.ACCENT_DISABLED; elseif(vOsVersion>newVersion(10,0)) accentState=enable?AccentState.ACCENT_ENABLE_BLURBEHIND:AccentState.ACCENT_DISABLED; else accentState=AccentState.ACCENT_DISABLED; if(opacity>1) opacity=1; varwindowHelper=newWindowInteropHelper(window); varaccent=newAccentPolicy(); varopacityIn=(uint)(255*opacity); accent.AccentState=accentState; if(enable) { varblurColor=(uint)((color.R<<0)|(color.G<<8)|(color.B<<16)|(color.A<<24)); varblurColorIn=blurColor; if(opacityIn>0) blurColorIn=(opacityIn<<24)|(blurColor&0xFFFFFF); elseif(opacityIn==0&&color.A==0) blurColorIn=(0x01<<24)|(blurColor&0xFFFFFF); if(accent.GradientColor==blurColorIn) returntrue; accent.GradientColor=blurColorIn; } varaccentStructSize=Marshal.SizeOf(accent); varaccentPtr=Marshal.AllocHGlobal(accentStructSize); Marshal.StructureToPtr(accent,accentPtr,false); vardata=newWindowCompositionAttributeData(); data.Attribute=WindowCompositionAttribute.WCA_ACCENT_POLICY; data.SizeOfData=accentStructSize; data.Data=accentPtr; SetWindowCompositionAttribute(windowHelper.Handle,refdata); Marshal.FreeHGlobal(accentPtr); returntrue; } privatestaticvoidwindow_Initialized(objectsender,EventArgse) { if(!(senderisWindowwindow)) return; varconfig=newWindowOldConfig { WindowStyle=window.WindowStyle, AllowsTransparency=window.AllowsTransparency, Background=window.Background }; varvWindowChrome=WindowChrome.GetWindowChrome(window); if(vWindowChrome==null) { window.WindowStyle=WindowStyle.None;//一定要将窗口的背景色改为透明才行 window.AllowsTransparency=true;//一定要将窗口的背景色改为透明才行 window.Background=newSolidColorBrush(_BackgtoundColor);//一定要将窗口的背景色改为透明才行 } else { config.WindowChrome=newWindowChrome { GlassFrameThickness=vWindowChrome.GlassFrameThickness }; window.Background=Brushes.Transparent;//一定要将窗口的背景色改为透明才行 varvGlassFrameThickness=vWindowChrome.GlassFrameThickness; vWindowChrome.GlassFrameThickness=newThickness(0,vGlassFrameThickness.Top,0,0); } SetWindowOldConfig(window,config); window.Initialized-=Window_Initialized; } privatestaticvoidWindow_Loaded(objectsender,RoutedEventArgse) { if(!(senderisWindowwindow)) return; varvblur=GetWindowAcrylicBlur(window); if(vBlur!=null) EnableAcrylicBlur(window,vBlur.BlurColor,vBlur.Opacity,true); window.Loaded-=Window_Loaded; } protectedoverrideFreezableCreateInstanceCore() { thrownewNotImplementedException(); } protectedoverridevoidOnChanged() { base.OnChanged(); } protectedoverridevoidOnPropertyChanged(DependencyPropertyChangedEventArgse) { base.OnPropertyChanged(e); } #region开启Win11风格 publicstaticWindowAcrylicBlurGetWindowAcrylicBlur(DependencyObjectobj) { return(WindowAcrylicBlur)obj.GetValue(WindowAcrylicBlurProperty); } publicstaticvoidSetWindowAcrylicBlur(DependencyObjectobj,WindowAcrylicBlurvalue) { obj.SetValue(WindowAcrylicBlurProperty,value); } publicstaticreadonlyDependencyPropertyWindowAcrylicBlurProperty= DependencyProperty.RegisterAttached("WindowAcrylicBlur",typeof(WindowAcrylicBlur), typeof(WindowAcrylicBlur), newPropertyMetadata(default(WindowAcrylicBlur),OnWindowAcryBlurPropertyChangedCallBack)); privatestaticvoidOnWindowAcryBlurPropertyChangedCallBack(DependencyObjectd, DependencyPropertyChangedEventArgse) { if(!(disWindowwindow)) 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) { varvConfig=GetWindowOldConfig(d); if(vConfig!=null) { window.WindowStyle=vConfig.WindowStyle; window.AllowsTransparency=vConfig.AllowsTransparency; window.Background=vConfig.Background; if(vConfig.WindowChrome!=null) { varvWindowChrome=WindowChrome.GetWindowChrome(window); if(vWindowChrome!=null) vWindowC编程客栈hrome.GlassFrameThickness=vConfig.WindowChrome.GlassFrameThickness; } } } if(e.OldValue==e.NewValue) { if(!window.IsLoaded) return; varvBlur=e.NewValueasWindowAcrylicBlur; if(vBlur==null) return; EnableAcrylicBlur(window,vBlur.BlurColor,vBlur.Opacity,true); } } #endregion #region内部设置 privatestaticWindowOldConfigGetWindowOldConfig(DependencyObjectobj) { return(WindowOldConfig)obj.GetValue(WindowOldConfigProperty); } privatestaticvoidSetWindowOldConfig(DependencyObjectobj,WindowOldConfigvalue) { obj.SetValue(WindowOldConfigProperty,value); } //UsingaDependencyPropertyasthebackingstoreforWindowOldConfig.Thisenablesanimation,styling,binding,etc... privatestaticreadonlyDependencyPropertyWindowOldConfigProperty= DependencyProperty.RegisterAttached("WindowOldConfig",typeof(WindowOldConfig),typeof(WindowAcrylicBlur), newPropertyMetadata(default(WindowOldConfig))); #endregion #region publicColorBlurColor { get=>(Color)GetValue(BlurColorProperty); set=>SetValue(BlurColorProperty,value); } //UsingaDependencyPropertyasthebackingstoreforBlurColor.Thisenablesanimation,styling,binding,etc... publicstaticreadonlyDependencyPropertyBlurColorProperty= DependencyProperty.Register("BlurColor",typeof(Color),typeof(WindowAcrylicBlur), newPropertyMetadata(default(Color))); publicdoubleOpacity { get=>(double)GetValue(OpacityProperty); set=>SetValue(OpacityProperty,value); } //UsingaDependencyPropertyasthebackingstoreforOpacity.Thisenablesanimation,styling,binding,etc... publicstaticreadonlyDependencyPropertyOpacityProperty= DependencyProperty.Register("Opahttp://www.devze.comcity",typeof(double),typeof(WindowAcrylicBlur), newPropertyMetadata(default(double))); #endregion } }
2) 使用AcrylicBlurWindowExample.xaml如下:
<Windowx:Class="WPFDevelopers.Samples.ExampleViews.AcrylicBlurWindowExample" XMLns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/200php6/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers" mc:Ignorable="d"WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize" Title="Login"Height="350"Width="400"> <wpfdev:WindowChrome.WindowChrome> <wpfdev:WindowChromeGlassFrameThickness="0100"/> </wpfdev:WindowChrome.WindowChrome> <wpfdev:WindowAcrylicBlur.WindowAcrylicBlur> <wpfdev:WindowAcrylicBlurBlurColor="AliceBlue"Opacity="0.2"/> </wpfdev:WindowAcrylicBlur.WindowAcrylicBlur> <Grid> <Grid.RowDefinitions> <RowDefinitionHeight="40"/> <RowDefinition/> </Grid.RowDefinitions> <StackPanelHorizontalAlignment="Right" Orientation="Horizontal" Grid.Column="1" wpfdev:WindowChrome.IsHitTestVisibleInChrome="True"> <ButtonStyle="{DynamicResourceWindowButtonStyle}" Command="{BindingCloseCommand,RelativeSource={RelativeSourceAncestorType=local:AcrylicBlurWindowExample}}"Cursor="Hand"> <PathWidth="10"Height="10" HorizontalAlignment="Center" VerticalAlignment="Center" Data="{DynamicResourcePathMetroWindowClose}" Fill="Red" Stretch="Fill"/> </Button> </StackPanel> <StackPanelGrid.Row="1"Margin="40,0,40,0" wpfdev:WindowChrome.IsHitTestVisibleInChrome="True"> <ImageSource="/WPFDevelopers.ico"Width="80"Height="80"/> <TextBoxwpfdev:ElementHelper.IsWatermark="True"wpfdev:ElementHelper.Watermark="账户"Margin="0,20,0,0"Cursor="Hand"/> <PasswordBoxwpfdev:ElementHelper.IsWatermark="True"wpfdev:ElementHelper.Watermark="密码"Margin="0,20,0,0"Cursor="Hand"/> <Buttonx:Name="LoginButton" Content="登录" Margin="0,20,0,0" Style="{StaticResourcePrimaryButton}"/> <GridMargin="02000"> <TextblockFontSize="12"> <HyperlinkForeground="Black"TextDecorations="None">忘记密码</Hyperlink> </TextBlock> <TextBlockFontSize="12"HorizontalAlignment="Right"Margin="00-10"> <Hypehttp://www.devze.comrlinkForeground="#4370F5"TextDecorations="None">注册账号</Hyperlink> </TextBlock> </Grid> </StackPanel> </Grid> </Window>
3) 使用AcrylicBlurWindowExample.xaml.cs如下:
usingSystem.Windows; usingSystem.Windows.Input; usingWPFDevelopers.Samples.Helpers; namespaceWPFDevelopers.Samples.ExampleViews { ///<summary> ///AcrylicBlurWindowExample.xaml的交互逻辑 ///</summary> publicpartialclassAcrylicBlurWindowExample:Window { publicAcrylicBlurWindowExample() { InitializeComponent(); } publicICommandCloseCommand=>newRelayCommand(obj=> 开发者_开发教程{ Close(); }); } }
实现效果
到此这篇关于WPF实现窗体亚克力效果的示例代码的文章就介绍到这了,更多相关WPF窗体亚克力内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!
精彩评论