开发者

WPF实现窗体亚克力效果的示例代码

wpF 窗体设置亚克力效果

框架使用大于等于.NET40

Visual Studio 2022

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

WindowAcrylicBlur 设置亚克力颜色。

Opacity 设置透明度。

WPF实现窗体亚克力效果的示例代码

实现代码

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实现窗体亚克力效果的示例代码的文章就介绍到这了,更多相关WPF窗体亚克力内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜