zoukankan      html  css  js  c++  java
  • WPF窗口阴影

    起因

    在以前项目中,需要给用户一定提示。设计师建议在鼠标进入时显示窗口阴影,离开时取消窗口阴影。

    尝试1

    很自然,都会想到直接在窗口的内容或者自定义窗口的最外层元素上加效果。示例如下:

    <Grid>
        <Grid.Effect>
            <DropShadowEffect x:Name="ShadowEffect"
                                                      BlurRadius="15"
                                                      Direction="270"
                                                      Opacity="0"
                                                      ShadowDepth="15"
                                                      Color="Yellow" />
        </Grid.Effect>
    </Grid>

    很不幸,上述方法不会生效。原因何在?窗口的非工作区(也就是Grid的四周)的渲染是由系统控制。虽然不清楚是绘出来了被遮住了还是根本没绘出来,但是告诉了我们此路不通。

    解决方案

    还好我们用的是WPF,可以自己定义模板和样式。于是简单测试了一下就发现了方案。下面就是我使用的样式一个示例(省略了模拟的控制按钮和其他的一些功能)

    <Style x:Key="ShadowWindow" TargetType="Window">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="AllowsTransparency" Value="True" />
        <Setter Property="WindowStyle" Value="None" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Window">
                    <Border Padding="15">
                        <Border Name="BdrShadow">
                            <ContentPresenter ContentSource="Content" />
                            <Border.Effect>
                                <DropShadowEffect x:Name="ShadowEffect"
                                                  BlurRadius="15"
                                                  Direction="270"
                                                  Opacity="0"
                                                  ShadowDepth="15"
                                                  Color="Yellow" />
                            </Border.Effect>
                        </Border>
                    </Border>
                    <ControlTemplate.Triggers>
                        <EventTrigger RoutedEvent="MouseEnter">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0:0:1"
                                                     Storyboard.TargetName="ShadowEffect"
                                                     Storyboard.TargetProperty="Opacity"
                                                     To="0.5" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                        <EventTrigger RoutedEvent="MouseLeave">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0:0:1"
                                                     Storyboard.TargetName="ShadowEffect"
                                                     Storyboard.TargetProperty="Opacity" />
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    注意事项

    • 必须将OverridesDefaultStyle和AllowsTransparency设为true。
    • 根据需要设置相应的属性,比如外层Border的Padding要与阴影的属性保持一致,示例中是15。

    不足

    1. 有时阴影显隐失灵 。
    2. 效率低下,特别是经常需要更新界面时(所以最后我们放弃这个方案了) 。
    3. 上述样式存在一个问题,即在用到界面验证时,会发生验证提示无法显示的情况。改进也很简单,在样式中手动添加一个AdornerLayer。原因在于验证常用的AdornedElementPlaceholder中包含一个Adorner,而Adorner必须寄宿于AdornerLayer。系统默认的Window样式中包含AdornerLayer,所以显示正常。
  • 相关阅读:
    电磁学讲义3:电场
    电磁学讲义2:库仑定律
    电磁学讲义1:静电的基本现象
    安卓(Android)手机如何安装APK?
    理论物理极础9:相空间流体和吉布斯-刘维尔定理
    物理学家的LOGO
    Zhulina 的高分子刷理论
    一步一步学Silverlight 2系列(5):实现简单的拖放功能
    地图上显示X,Y 坐标代码
    一步一步学Silverlight 2系列(4):鼠标事件处理
  • 原文地址:https://www.cnblogs.com/yiyan127/p/WPF-WindowShadow.html
Copyright © 2011-2022 走看看