起因 在以前項目中,需要給用戶一定提示。設計師建議在滑鼠進入時顯示視窗陰影,離開時取消視窗陰影。 嘗試1 很自然,都會想到直接在視窗的內容或者自定義視窗的最外層元素上加效果。示例如下: <Grid> <Grid.Effect> <DropShadowEffect x:Name="ShadowEffe ...
起因
在以前項目中,需要給用戶一定提示。設計師建議在滑鼠進入時顯示視窗陰影,離開時取消視窗陰影。
嘗試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。
不足
- 有時陰影顯隱失靈 。
- 效率低下,特別是經常需要更新界面時(所以最後我們放棄這個方案了) 。
- 上述樣式存在一個問題,即在用到界面驗證時,會發生驗證提示無法顯示的情況。改進也很簡單,在樣式中手動添加一個AdornerLayer。原因在於驗證常用的AdornedElementPlaceholder中包含一個Adorner,而Adorner必須寄宿於AdornerLayer。系統預設的Window樣式中包含AdornerLayer,所以顯示正常。