65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.60/5 (16投票s)

2008 年 1 月 10 日

CPOL

2分钟阅读

viewsIcon

152256

downloadIcon

5272

一个示例,展示如何仅用一行代码为 WPF 应用程序添加玻璃效果!

注释

关于附加属性的更详细解释可以在这里找到。

引言

在回顾了 Blendables 之后,我决定研究一下使用附加属性也允许窗口开启其玻璃效果会有多困难。(Blendables 的回顾可以在这里找到。)

附加属性在 WPF 中被广泛使用(DockPanel.DockCanvas.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>!!!

下一步是在附加属性更改时附加一个事件处理程序。在这个事件处理程序内部,我可以检查附加属性是否更改为 TrueFalseIsEnabled)。

如果 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 日:初始发布

链接

© . All rights reserved.