使用附加属性为 WPF 添加玻璃效果






4.60/5 (16投票s)
一个示例,
注释
关于附加属性的更详细解释可以在这里找到。
引言
在回顾了 Blendables
之后,我决定研究一下使用附加属性也允许窗口开启其玻璃效果会有多困难。(Blendables
的回顾可以在这里找到。)
附加属性在 WPF 中被广泛使用(DockPanel.Dock
、Canvas.Left
等),但它们也具有简化其他许多任务的潜力(在 Windows 上设置玻璃效果,为 ListBox
添加拖放功能,启用控件上的拼写检查)。
我希望能够通过一行代码来开启 Aero 玻璃效果
<Window x:Class="GlassEffectDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace: GlassEffectDemo"
src:GlassEffect.IsEnabled="True"
Title="GlassEffect demo" Height="300" Width="300">
<Grid>
</Grid>
</Window>
Aero 玻璃效果
我不会过多地详细介绍如何启用玻璃效果。(这已经在网上被详细介绍过了。)这篇文章将更多地关注如何使用附加属性来开启玻璃效果!
这是我的附加属性 IsEnabled
的定义
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled",
typeof(Boolean), typeof(GlassEffect),
new FrameworkPropertyMetadata(OnIsEnabledChanged));
public static void SetIsEnabled(DependencyObject element, Boolean value)
{
element.SetValue(IsEnabledProperty, value);
}
public static Boolean GetIsEnabled(DependencyObject element)
{
return (Boolean)element.GetValue(IsEnabledProperty);
}
public static void OnIsEnabledChanged
(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if ((bool)args.NewValue == true)
{
try
{
Window wnd = (Window)obj;
wnd.Loaded +=new RoutedEventHandler(wnd_Loaded);
}
catch (Exception)
{
//Attached property is not set for a Window, do nothing!!!
}
}
}
重要的是要注意,所有附加属性都必须使用 DependencyProperty.RegisterAttached
注册,并且它们也必须具有 Get<PropertyName>
和 Set<PropertyName>
!!!
下一步是在附加属性更改时附加一个事件处理程序。在这个事件处理程序内部,我可以检查附加属性是否更改为 True
或 False
(IsEnabled
)。
如果 IsEnabled
更改为 true
,那么我会将一个事件处理程序添加到 Windows 加载事件。这是加载事件处理程序... 它所做的只是添加玻璃效果
static void wnd_Loaded(object sender, RoutedEventArgs e)
{
Window wnd = (Window)sender;
Brush originalBackground = wnd.Background;
wnd.Background = Brushes.Transparent;
try {
IntPtr mainWindowPtr = new WindowInteropHelper(wnd).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);
System.Drawing.Graphics desktop =
System.Drawing.Graphics.FromHwnd(mainWindowPtr);
MARGINS margins = new MARGINS();
margins.cxLeftWidth = -1;
margins.cxRightWidth = -1;
margins.cyTopHeight = -1;
margins.cyBottomHeight = -1;
DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
}
catch (DllNotFoundException)
{
wnd.Background = originalBackground;
}
}
现在可以通过使用一行代码来开启玻璃效果!!!
如往常一样,请评论我如何改进我的文章,并对这篇文章进行评分(即使你认为它完全没用!)
历史
- 2008 年 1 月 10 日:初始发布