如何使用触发器来定位效果?
问题描述:
在我的WPF应用程序中,我正在为ComboBox编写一个自定义模板。我想组合框获得提升的阴影效果,当用户将鼠标放在它,所以我尝试写这样的代码:如何使用触发器来定位效果?
<ControlTemplate TargetType="{x:Type ComboBox}">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4" SnapsToDevicePixels="True">
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
</Grid.ColumnDefinitions>
<Border x:Name="Shadow"
Grid.Column="0" Grid.ColumnSpan="2"
Margin="-3"
Background="{DynamicResource L1Brush}">
<Border.Effect>
<DropShadowEffect x:Name="ShadowEffect"
BlurRadius="0" ShadowDepth="0" />
</Border.Effect>
</Border>
<!-- rest of the template -->
</Grid>
</Border>
<ControlTemplate.Triggers>
<!-- other triggers -->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="ShadowEffect" Property="DropShadowEffect.BlurRadius" Value="5" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="ShadowEffect" Property="DropShadowEffect.BlurRadius" Value="5" />
</Trigger>
<!-- other triggers -->
</ControlTemplate.Triggers>
</ControlTemplate>
然而,在运行时,它抛出一个错误,理由是该名称ShadowEffect
不存在。我如何完成这项工作?如果我想动画的话,我会如何从Storyboard中引用ShadowEffect
?
我意识到我可以设置边框的整个Effect
属性,但是如果我尝试添加动画,这种方法会分崩离析。
答
这实际上是一种烦人的;你不能给Setter
一个路径。即使这里有任何东西有一个名为DropShadowEffect
的属性,你也无法得到它。你可以使用动画,但这更加冗长,我没有整夜。
你可以做的是旧的Tag
黑客。 Tag
适合抓取,并且它是一个依赖项属性,所以它会在其值更改时更新绑定。 Border.Tag
被初始化为零,设置者将其设置为5,并且DropShadowEffect
将其BlurRadius
绑定到它。
<ControlTemplate TargetType="{x:Type ComboBox}" x:Key="ComboTemplate">
<Border x:Name="templateRoot"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4" SnapsToDevicePixels="True">
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="0" MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" />
</Grid.ColumnDefinitions>
<Border
x:Name="Shadow"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="-3"
Background="{DynamicResource L1Brush}"
Tag="0"
>
<Border.Effect>
<DropShadowEffect
BlurRadius="{Binding Tag, RelativeSource={RelativeSource AncestorType=Border}}"
ShadowDepth="0"
/>
</Border.Effect>
</Border>
<!-- rest of the template -->
</Grid>
</Border>
<ControlTemplate.Triggers>
<!-- other triggers -->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Shadow" Property="Tag" Value="5" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="Shadow" Property="Tag" Value="5" />
</Trigger>
<!-- other triggers -->
</ControlTemplate.Triggers>
</ControlTemplate>
这是一个聪明的解决方案,谢谢!但一两件事 - ' BeginStoryboard> 似乎可以做到,但动画非常不稳定。为什么? –
333
@ 333你需要在DoubleAnimation IIRC上设置From和To。这是我希望的解决方案,但没有时间查找。现在我在我前往的酒吧。 –