我正在使用WPF Expander来显示许多模拟过程变量。
当其中一个变量进入“警告”或“警报”状态时,我想让扩展器的边框“发光”(或闪烁)。
为了达到这个目的,我在视图模型中使用了一些绑定到几个布尔属性的数据触发器('AnalogWarningActive'和'AnalogAlarmActive')。数据触发器启动故事板,动画扩展器边界不透明度。
数据触发器按照我的预期工作:出现正确的边框颜色并开始不透明度动画。但是,有两个问题:
整个扩展器(以及所有包含的控件)的不透明度正在发生变化,而不仅仅是其边框的不透明度。
当'AnalogWarningActive'和'AnalogAlarmActive'标签返回False时,边框消失,但不透明的动画会无限期地继续(即整个扩展器继续淡入淡出)。
这是我正在使用的xaml:
<SolidColorBrush x:Key="AnalogAlarmBrush" Color="#FFFF8080" />
<SolidColorBrush x:Key="AnalogWarningBrush" Color="#FFFFFF80" />
<Storyboard x:Key="AlarmBorderFlasher" AutoReverse="True" RepeatBehavior="Forever">
<DoubleAnimation
Storyboard.TargetProperty="(Border.Opacity)"
From="1.0" To="0.4"
Duration="0:0:0.8" />
</Storyboard>
<Expander Header="Test Data" IsExpanded="True">
<Expander.Style>
<Style TargetType="{x:Type Expander}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=AnalogWarningActive}" Value="True" >
<DataTrigger.EnterActions>
<BeginStoryboard Name="WarningBorderStoryboard" Storyboard="{StaticResource AlarmBorderFlasher}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="WarningBorderStoryboard" />
</DataTrigger.ExitActions>
<DataTrigger.Setters>
<Setter Property="BorderBrush" Value="{StaticResource AnalogWarningBrush}" />
<Setter Property="BorderThickness" Value="4" />
</DataTrigger.Setters>
</DataTrigger>
<DataTrigger Binding="{Binding Path=AnalogAlarmActive}" Value="True" >
<DataTrigger.EnterActions>
<BeginStoryboard Name="AlarmBorderStoryboard" Storyboard="{StaticResource AlarmBorderFlasher}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="AlarmBorderStoryboard" />
</DataTrigger.ExitActions>
<DataTrigger.Setters>
<Setter Property="BorderBrush" Value="{StaticResource AnalogAlarmBrush}" />
<Setter Property="BorderThickness" Value="4" />
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Expander.Style>
<!-- snipped the contents of the expander (a tabcontrol and a few text boxes, labels, etc)-->
</Expander>
答案 0 :(得分:1)
问题#1
Visual等视觉上的不透明度设置会影响Visual及其所有后代。这就是设置Border.Opacity使一切都消失的原因。
您有两种选择:1。为边框Stroke属性设置动画,或2.将内容更改为不是Border的后代。
动画Stroke属性对代码来说是微不足道的,但缺点是并非所有画笔都能轻松实现透明和背面的动画。例如,使用渐变画笔很难。此外,如果你的边框是各种颜色,并且你不想100%透明,那么没有好的方法可以在不改变颜色的情况下为笔划设置动画。
将内容更改为不是Border的后代非常简单,在大多数情况下我会倾向于这样做。只需更换:
<Border x:Name="MyBorder" Stroke="Red" StrokeThickness="3" CornerRadius="6">
<my:ContentHere />
</Border>
用这个:
<Grid>
<Border x:Name="MyBorder" Stroke="Red" StrokeThickness="3" Stroke="Red" CornerRadius="6">
<Border Stroke="Transparent" StrokeThickness="3" CornerRadius="Red">
<my:ContentHere />
</Border>
</Grid>
现在,可见边框的不透明度可以设置动画,而透明边框可以控制子项的布局和剪裁。
如果您没有任何CornerRadius或其他有趣的业务,您可以在内容上设置边距并放弃透明边框:
<Grid>
<Border x:Name="MyBorder" Stroke="Red" StrokeThickness="3" />
<my:ContentHere Margin="3" />
</Grid>
问题#2
乍一看,我发现你的XAML没有任何问题会导致动画在触发值恢复为假之后继续运行,但我看起来并不是很紧密。根据我的注意,我认为它会以当前值停止动画,而不是让它继续运行。
您可以尝试使用RemoveStoryboard替换StopStoryboard。 RemoveStoryboard应将动画属性重置为原始值。