WPF 窗體設置亞克力效果

?WPF 窗體設置亞克力效果

控件名:WindowAcrylicBlur

作者: WPFDevelopersOrg ?- 吳鋒

原文鏈接: ? ?https://github.com/WPFDevelopersOrg/WPFDevelopers

  • 框架使用大于等于.NET40

  • Visual Studio 2022

  • 項目使用 MIT 開源許可協議。

  • WindowAcrylicBlur 設置亞克力顏色。

  • Opacity 設置透明度。

c7f3087818a44f315cddef317c996722.png

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))?//1809accentState?=?enable???AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND?:?AccentState.ACCENT_DISABLED;else?if?(vOsVersion?>?new?Version(10,?0))accentState?=?enable???AccentState.ACCENT_ENABLE_BLURBEHIND?:?AccentState.ACCENT_DISABLED;elseaccentState?=?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#regionpublic?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如下:

<Window?x:Class="WPFDevelopers.Samples.ExampleViews.AcrylicBlurWindowExample"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: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:WindowChrome??GlassFrameThickness="0?1?0?0"/></wpfdev:WindowChrome.WindowChrome><wpfdev:WindowAcrylicBlur.WindowAcrylicBlur><wpfdev:WindowAcrylicBlur?BlurColor="AliceBlue"?Opacity="0.2"/></wpfdev:WindowAcrylicBlur.WindowAcrylicBlur><Grid><Grid.RowDefinitions><RowDefinition?Height="40"/><RowDefinition/></Grid.RowDefinitions><StackPanel?HorizontalAlignment="Right"?Orientation="Horizontal"Grid.Column="1"wpfdev:WindowChrome.IsHitTestVisibleInChrome="True"><Button?Style="{DynamicResource?WindowButtonStyle}"Command="{Binding?CloseCommand,RelativeSource={RelativeSource?AncestorType=local:AcrylicBlurWindowExample}}"?Cursor="Hand"><Path?Width="10"?Height="10"HorizontalAlignment="Center"VerticalAlignment="Center"Data="{DynamicResource?PathMetroWindowClose}"Fill="Red"Stretch="Fill"?/></Button></StackPanel><StackPanel?Grid.Row="1"?Margin="40,0,40,0"wpfdev:WindowChrome.IsHitTestVisibleInChrome="True"><Image?Source="/WPFDevelopers.ico"?Width="80"?Height="80"/><TextBox?wpfdev:ElementHelper.IsWatermark="True"?wpfdev:ElementHelper.Watermark="賬戶"?Margin="0,20,0,0"?Cursor="Hand"/><PasswordBox?wpfdev:ElementHelper.IsWatermark="True"?wpfdev:ElementHelper.Watermark="密碼"??Margin="0,20,0,0"?Cursor="Hand"/><Button?x:Name="LoginButton"?Content="登?錄"?Margin="0,20,0,0"Style="{StaticResource?PrimaryButton}"/><Grid?Margin="0?20?0?0"><TextBlock?FontSize="12"><Hyperlink?Foreground="Black"?TextDecorations="None">忘記密碼</Hyperlink></TextBlock><TextBlock?FontSize="12"?HorizontalAlignment="Right"?Margin="0?0?-1?0"><Hyperlink?Foreground="#4370F5"?TextDecorations="None">注冊賬號</Hyperlink></TextBlock></Grid></StackPanel></Grid>
</Window>

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

using?System.Windows;
using?System.Windows.Input;
using?WPFDevelopers.Samples.Helpers;namespace?WPFDevelopers.Samples.ExampleViews
{///?<summary>///?AcrylicBlurWindowExample.xaml?的交互邏輯///?</summary>public?partial?class?AcrylicBlurWindowExample?:?Window{public?AcrylicBlurWindowExample(){InitializeComponent();}public?ICommand?CloseCommand?=>?new?RelayCommand(obj?=>{Close();});}
}

?鳴謝 - 吳鋒

4dec8c8410ec1d3800ba58f262a38c92.gif

Github|AcrylicBlurWindowExample[1]
碼云|AcrylicBlurWindowExample[2]
使用 SetWindowCompositionAttribute 來控制程序的窗口邊框和背景可以做 Acrylic 亞克力效果、模糊效果、主題色效果等[3]

參考資料

[1]

Github|AcrylicBlurWindowExample: https://github.com/WPFDevelopersOrg/WPFDevelopers/blob/master/src/WPFDevelopers.Samples/ExampleViews/AcrylicBlurWindowExample.xaml

[2]

碼云|AcrylicBlurWindowExample: https://gitee.com/WPFDevelopersOrg/WPFDevelopers/blob/master/src/WPFDevelopers.Samples/ExampleViews/AcrylicBlurWindowExample.xaml

[3]

使用 SetWindowCompositionAttribute 來控制程序的窗口邊框和背景可以做 Acrylic 亞克力效果、模糊效果、主題色效果等: https://blog.walterlv.com/post/set-window-composition-attribute.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282288.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282288.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282288.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JS向后臺傳遞json數組對象

var Obj [];            //一下代碼可以循環插入            var returnObj new Object();//創建一個對象returnObj.id “123”&#xff1b;returnObj.money 456“”;Obj.push(returnObj);           JS中將Obj對象進行序列化操作   …

ArrayBlockingQueue跟LinkedBlockingQueue的區別

1.隊列中的鎖的實現不同 ArrayBlockingQueue中的鎖是沒有分離的&#xff0c;即生產和消費用的是同一個鎖&#xff1b; LinkedBlockingQueue中的鎖是分離的&#xff0c;即生產用的是putLock&#xff0c;消費是takeLock 2.在生產或消費時操作不同 ArrayBlockingQueue基于數組&…

jqGrid('setSelection',rowid)報Cannot read property 'multiple' of undefined

項目組非要上jeeweb框架&#xff0c;用jqgrid大量iframe做為前端框架&#xff0c;臃腫不堪。 今天上午&#xff0c;在進行選定操作jqGrid(setSelection,rowid)報Cannot read property multiple of undefined&#xff0c;怎么分析也找不出原因&#xff0c;最后百度搜了一下竟然有…

數據分塊加載——BigPipe 技術【類似facebook】

一、原理 分塊加載&#xff0c;加載完一塊&#xff0c;就先把頁面數據刷給用戶&#xff0c;再加載下面的&#xff0c;直到加載完畢二、基礎需知&#xff1a;三、服務端和php的相應配置 如果想實現分塊加載【bigpipe技術】&#xff0c;還需要對nginx.conf 和 php.ini 進行相應配…

Maven -- 在進行war打包時用正式環境的配置覆蓋開發環境的配置

我們的配置文件一般都放在 src/main/resource 目錄下。 假定我們的正式環境配置放在 src/main/online-resource 目錄下。 那么打成war包時&#xff0c;我們希望用online-resource下的配置文件取代resource 下的配置文件。 pom.xml 插件配置&#xff1a; <plugin><gr…

右鍵一下,哇塞!

面向 Dev 頻道的 Windows 預覽體驗成員微軟推送了 Windows 11 預覽版Insider Preview Build 25211主要變化1.微軟改進了 Windows 11 小組件面板&#xff0c;小組件面板中的添加按鈕更加醒目&#xff0c;點擊用戶頭像將打開小組件設置。Windows 11 小組件由 Microsoft Edge 瀏覽…

前端學習 -- Css -- 內聯元素的盒模型

內聯元素不能設置width和height&#xff1b;設置水平內邊距,內聯元素可以設置水平方向的內邊距&#xff1a;padding-left&#xff0c;padding-right&#xff1b;垂直方向內邊距&#xff0c;內聯元素可以設置垂直方向內邊距&#xff0c;但是不會影響頁面的布局&#xff1b;為元素…

Redis 數據持久化的方案的實現

一、需要了解的基礎 1、Redis實現數據持久化的兩種實現方式&#xff1a; RDB&#xff1a;指定的時間間隔內保存數據快照 AOF&#xff1a;先把命令追加到操作日志的尾部&#xff0c;保存所有的歷史操作二、RDB 實現 Redis數據持久化&#xff08;默認方式&#xff09;1、編輯 red…

div剩余空間填滿

div里有一個固定高度的div使其另一個div填滿空間&#xff0c;外層div設置的高度為百分比&#xff0c;給外層一個相對定位&#xff0c;設置想要充滿的div高度為100%&#xff0c;其中這次有個要求&#xff0c;使其填充div里面的內容距離固定高度div30px&#xff1b;給填充div一個…

快速生成快遞柜唯一取件碼

曾管理一萬多臺快遞柜&#xff0c;優化了系統中生成唯一取件碼的算法。項目&#xff1a;https://github.com/nnhy/PickupCode新建項目&#xff0c;添加 Nuget 應用 NewLife.Redis &#xff0c;借助其Add去重能力。代碼如下&#xff1a;private static void Main(string[] args)…

自動調試自動編譯五分鐘上手

Browsersync能讓瀏覽器實時、快速響應您的文件更改&#xff08;html、js、css、sass、less等&#xff09;并自動刷新頁面。更重要的是 Browsersync可以同時在PC、平板、手機等設備下進項調試。 無論您是前端還是后端工程師&#xff0c;使用它將提高您30%的工作效率。 MD5加密&a…

六臺機器搭建RedisCluster分布式集群

一、RedisCluster結構二、redis Cluster集群搭建1、修改redis.conf中需要更改的配置 bind 改成當前ip cluster-enabled yes #允許redis集群 cluster-config-file nodes-6379.conf #集群配置文件 cluster-node-timeout 15000 #集群中節點允許失聯的最大時間15s 注&#xff1…

C# 的 async/await 其實是stackless coroutine

注&#xff1a; 最近Java 19引入的虛擬線程火熱&#xff0c;還有很多人羨慕 go的 coroutine&#xff0c;很多同學一直有一個疑問&#xff1a; C# 有 虛擬線程或者 coroutine嗎&#xff0c;下面的這個回答可以解決問題。這里節選的是知乎上的hez2010 的高贊回答&#xff1a;http…

推薦使用typora

最近在網上接觸到一款全新的markdown寫作工具——typora。 現在它已經是我的主要寫作工具了。 甚至我也也會利用它安排自己的工作和任務。 typora介紹 下載鏈接特色&#xff1a;可以即時渲染markdown語法的書寫工具總算找到了&#xff0c;終于不用再糾結發生語法錯誤&#xff0…

中文詞頻統計

import jiebafoopen(text.txt,r,encodingutf-8)tfo.read()fo.close() wordsjieba.cut(t)dic{}for w in words: if len(w)1: continue else: dic[w]dic.get(w,0)1wc list(dic.items())wc.sort(keylambda x:x[1],reverse True)for i in range(20): print(wc[i]) 轉載于:https:/…

實現html錨點的兩種方式

1&#xff0c;a標簽name屬性。 2&#xff0c;使用標簽的id屬性&#xff1b;

mysql實現讀寫分離

一、環境介紹&#xff1a; LNMP vmware workstation pro配置了3個虛擬機&#xff0c;均安裝了LNMP環境&#xff1a; Pro &#xff1a;192.168.0.105 Pro2&#xff1a;192.168.0.106 Pro3&#xff1a;192.168.0.107 二、Mysql主從復制同步的實現 https://blo…

[BZOJ1509][NOI2003]逃學的小孩

1509: [NOI2003]逃學的小孩 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 968 Solved: 489[Submit][Status][Discuss]Description Input 第一行是兩個整數N&#xff08;3 ? N ? 200000&#xff09;和M&#xff0c;分別表示居住點總數和街道總數。以下M行&#xff0c;每行…

十一隨筆|讀書

十一放假回老家前三天一直下雨&#xff0c;沒法幫父母干農活&#xff0c;陰雨天氣農村就閑下來了親戚間走動&#xff0c;長輩們談論孩子不好好學習&#xff0c;孩子抱怨學習沒用大學畢業照樣找不到工作。現在大學生就業現狀確實不容樂觀&#xff0c;當下不好好學習沒有拖底&…

yii之behaviors

BaseController: protected $actions [*];protected $except [];protected $mustlogin [];protected $verbs [];// 行為過濾public function behaviors(){return [access > [class > \yii\filters\AccessControl::className(),only > $this->actions, // 針對哪…