WPF扩展器边框动画会影响所有包含的控件吗?

时间:2009-11-09 15:44:20

标签: c# wpf xaml storyboard

我正在使用WPF Expander来显示许多模拟过程变量。

当其中一个变量进入“警告”或“警报”状态时,我想让扩展器的边框“发光”(或闪烁)。

为了达到这个目的,我在视图模型中使用了一些绑定到几个布尔属性的数据触发器('AnalogWarningActive'和'AnalogAlarmActive')。数据触发器启动故事板,动画扩展器边界不透明度。

数据触发器按照我的预期工作:出现正确的边框颜色并开始不透明度动画。但是,有两个问题:

  1. 整个扩展器(以及所有包含的控件)的不透明度正在发生变化,而不仅仅是其边框的不透明度。

  2. 当'AnalogWarningActive'和'AnalogAlarmActive'标签返回False时,边框消失,但不透明的动画会无限期地继续(即整个扩展器继续淡入淡出)。

  3. 这是我正在使用的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>
    

1 个答案:

答案 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应将动画属性重置为原始值。