Bouton animé sur MouseOver et MouseDown

je fabrique mon propre ControlTemplate pour un bouton standard dans WPF. Je veux changer l'arrière-plan de mon bouton quand l'utilisateur survole le bouton avec la souris, mais aussi quand l'utilisateur appuie sur le bouton (à une autre couleur encore). Cela semble être un comportement commun, mais je ne peux pas le faire fonctionner.

mon modèle se compose d'une bordure avec une Image à l'intérieur. C'est la couleur de fond (un gradient vraiment) de la frontière que je veux animer. J'ai déclenche dans mon modèle active les animations (storyboards).

Le MouseOver/Out fonctionne très bien. Mon problème se produit quand j'appuie sur le bouton. L'animation de presse fonctionne comme il se doit, tout comme l'animation de publication. Mais après ça, la souris ne s'enfuira plus. Le bouton est coincé dans l'État de MouseOver.

Qu'est-ce que je fais de mal?

<ControlTemplate TargetType="{x:Type Button}">
    <ControlTemplate.Resources>
        <Storyboard x:Key="MouseOverAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffefefff" Duration="0:0:0.2" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ffc7c7ff" Duration="0:0:0.2" />
        </Storyboard>
        <Storyboard x:Key="MouseOutAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffeeeeee" Duration="0:0:0.2" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ffcccccc" Duration="0:0:0.2" />
        </Storyboard>
        <Storyboard x:Key="MouseDownAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffc7c7ff" Duration="0:0:0.1" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ff9a9aff" Duration="0:0:0.1" />
        </Storyboard>
        <Storyboard x:Key="MouseUpAnimation">
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" Storyboard.TargetProperty="Color" To="#ffefefff" Duration="0:0:0.1" />
            <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" Storyboard.TargetProperty="Color" To="#ffc7c7ff" Duration="0:0:0.1" />
        </Storyboard>
    </ControlTemplate.Resources>


    <Border x:Name="ButtonBorder" CornerRadius="0" BorderBrush="#55aaaaaa" BorderThickness="1" Width="23" Height="22">
        <Border.Background>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                <GradientBrush.GradientStops>
                    <GradientStop x:Name="ButtonBorderGradientStop1" Color="#ffeeeeee" Offset="0.0" />
                    <GradientStop x:Name="ButtonBorderGradientStop2" Color="#ffcccccc" Offset="1.0" />
                </GradientBrush.GradientStops>
            </LinearGradientBrush>
        </Border.Background>
        <Image x:Name="ButtonIcon" Source="icons/searchicon_bw.png" Width="16" Height="16" />
    </Border>


    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource MouseOverAnimation}" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource MouseOutAnimation}" />
            </Trigger.ExitActions>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource MouseDownAnimation}" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard Storyboard="{StaticResource MouseUpAnimation}" />
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers> 
</ControlTemplate>
9
demandé sur haagel 2010-03-12 15:53:55

1 réponses

Les Animations ont une propriété appelée FillBehavior, la valeur par défaut est HoldEnd.

Une fois votre animation MouseUp terminée, elle conserve la valeur empêchant l'animation de s'afficher correctement. L'animation de sortie de la souris fonctionne effectivement, mais est couverte par l'animation de sortie de la souris. Si vous renversez l'ordre de vos déclencheurs, mettant IsPressed en premier, vous pouvez voir que L'animation IsMouseOver couvre tous les IsPressed animation.

Vous pouvez définir FillBehaviorArrêt pour que les animations cessent de couvrir la propriété lorsqu'elles sont terminées.

dans votre cas, configurer FillBehavior pour arrêter sur votre MouseOutAnimation et MouseUpAnimation fait l'affaire.

(dans cet exemple mettre sur le storyboard de sorte qu'il s'applique à toutes les animations contenues.)

<ControlTemplate.Resources> 
    <Storyboard x:Key="MouseOverAnimation" Storyboard.TargetProperty="Color"> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffefefff" Duration="0:0:0.2" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ffc7c7ff" Duration="0:0:0.2" /> 
    </Storyboard> 
    <Storyboard x:Key="MouseOutAnimation" Storyboard.TargetProperty="Color"
                FillBehavior="Stop"> <!-- <=================== -->
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffeeeeee" Duration="0:0:0.2" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ffcccccc" Duration="0:0:0.2" /> 
    </Storyboard> 
    <Storyboard x:Key="MouseDownAnimation" Storyboard.TargetProperty="Color"> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffc7c7ff" Duration="0:0:0.1" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ff9a9aff" Duration="0:0:0.1" /> 
    </Storyboard> 
    <Storyboard x:Key="MouseUpAnimation" Storyboard.TargetProperty="Color"
                FillBehavior="Stop">  <!-- <=================== -->
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop1" To="#ffefefff" Duration="0:0:0.1" /> 
        <ColorAnimation Storyboard.TargetName="ButtonBorderGradientStop2" To="#ffc7c7ff" Duration="0:0:0.1" /> 
    </Storyboard> 
</ControlTemplate.Resources>

Vous pouvez trouver plus d'informations sur FillBehavior dans L'Animation D'article MSDN vue D'ensemble que se passe-t-il après la fin d'une Animation?.

10
répondu Kep Amun 2010-03-12 14:20:51