Question

J'utilise un WPF Expander pour afficher un certain nombre de variables de processus analogiques.

Je veux faire (ou flash) de frontière « lueur » l'expansion lorsque l'une de ces variables entre dans un état « avertissement » ou « alarme ».

Pour ce faire, j'utilise certaines données déclenche lié à un couple de propriétés booléennes dans mon modèle de vue ( « de AnalogWarningActive » et « AnalogAlarmActive »). Les données déclenche le coup d'envoi d'un story-board qui anime l'opacité des frontières d'extension.

Les données déclenche le travail que je pense: la bonne couleur de bordure apparaît et l'animation d'opacité commence. Cependant, il y a 2 problèmes:

  1. L'opacité de l'ensemble d'extension (et tous les contrôles contenus) est en train de changer et non pas seulement l'opacité de sa frontière.

  2. Quand le 'AnalogWarningActive' et 'AnalogAlarmActive' étiquettes retournent sur False, la frontière disparaît, mais l'animation opactiy continue indéfiniment (ie. L'extension entière continue à disparaître dans et hors).

Voici le XAML J'utilise:

<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>
Était-ce utile?

La solution

Question # 1

Le paramètre Opacité sur un visuel tel que la frontière affecte que Visual et tous ses descendants. Voilà pourquoi la mise en Border.Opacity fait tout disparaître.

Vous avez deux choix: 1. Animer la propriété des maladies à la frontière, ou 2. Modifiez le contenu de ne pas être un descendant de la frontière

.

Animer la propriété L'AVC est trivial au code, mais présente l'inconvénient que tous les brosses sont facilement animable à la transparence et à l'arrière. Par exemple, il est difficile avec des brosses à gradient. De plus, si vos frontières étaient une variété de couleurs et vous ne voulez pas aller à 100% transparent il n'y a pas de bonne façon d'animer le temps sans changer la couleur.

Modification du contenu de ne pas être un descendant de la frontière est très simple, et est ce que je serais enclin à faire dans la plupart des cas. Il suffit de remplacer:

<Border x:Name="MyBorder" Stroke="Red" StrokeThickness="3" CornerRadius="6">
  <my:ContentHere />
</Border>

avec ceci:

<Grid>
  <Border x:Name="MyBorder" Stroke="Red" StrokeThickness="3" Stroke="Red" CornerRadius="6">
  <Border Stroke="Transparent" StrokeThickness="3" CornerRadius="Red">
    <my:ContentHere />
  </Border>
</Grid>

Maintenant, l'opacité de la frontière visible peut être animé, tandis que le transparent contrôle la mise en page et la coupure de l'enfant.

Si vous n'avez pas CornerRadius ou d'autres affaires drôle, il vous suffit de définir une marge sur le contenu et renoncer à la frontière transparente:

<Grid>
  <Border x:Name="MyBorder" Stroke="Red" StrokeThickness="3" />
  <my:ContentHere Margin="3" />
</Grid>

Question # 2

À première vue, je ne vois aucun problème avec votre XAML qui provoquerait l'animation pour continuer à fonctionner après que la valeur de déclenchement retourne false, mais je n'ai pas regardé de très près. D'après ce que j'ai remarqué, je pense qu'il arrêterait l'animation à la valeur actuelle, ne pas laisser courir.

Vous pouvez essayer de remplacer StopStoryboard avec RemoveStoryboard. RemoveStoryboard devrait réinitialiser les propriétés d'animation à leurs valeurs d'origine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top