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,所以顯示正常。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM