2010-08-18 2 views
3

J'ai une application WPF qui a une listbox sur laquelle j'essaie d'appliquer des effets de survol. Tout fonctionne très bien quand j'utilise Setter s simple pour changer la couleur d'arrière-plan sur mouseover/sélection, mais j'ai pensé qu'il serait plus agréable s'il animait entre les états, donc j'ai changé Setter s pour entrer/sortir Storyboard s. Tout fonctionne bien au départ (le mouseover s'anime en &, la sélection s'anime en &), mais une fois que quelque chose a été sélectionné puis désélectionné, il ne fera plus jamais l'effet de mouseover.Utilisation d'animations de storyboard pour le survol et la sélection dans WPF ListBoxItems

Voici l'exemple de code minimal pour montrer la question:

<Window x:Class="WpfTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="500" Width="500"> 
    <Window.Resources> 
    <Style x:Key="ListboxItemStyle" TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type ListBoxItem}"> 
      <Border x:Name="border" BorderThickness="1" Height="50" Background="#000"> 
       <ContentPresenter /> 
      </Border> 
      <ControlTemplate.Triggers> 
       <MultiTrigger> 
       <MultiTrigger.Conditions> 
        <Condition Property="IsMouseOver" Value="True" /> 
        <Condition Property="IsSelected" Value="False" /> 
       </MultiTrigger.Conditions> 
       <MultiTrigger.EnterActions> 
        <BeginStoryboard> 
        <Storyboard> 
         <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="border" 
          Storyboard.TargetProperty="Background.Color" To="#00F" /> 
        </Storyboard> 
        </BeginStoryboard> 
       </MultiTrigger.EnterActions> 
       <MultiTrigger.ExitActions> 
        <BeginStoryboard> 
        <Storyboard> 
         <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="border" 
          Storyboard.TargetProperty="Background.Color" To="#008" /> 
        </Storyboard> 
        </BeginStoryboard> 
       </MultiTrigger.ExitActions> 
       </MultiTrigger> 
       <Trigger Property="IsSelected" Value="True"> 
       <Trigger.EnterActions> 
        <BeginStoryboard> 
        <Storyboard> 
         <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="border" 
          Storyboard.TargetProperty="Background.Color" To="#F00" /> 
        </Storyboard> 
        </BeginStoryboard> 
       </Trigger.EnterActions> 
       <Trigger.ExitActions> 
        <BeginStoryboard> 
        <Storyboard> 
         <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="border" 
          Storyboard.TargetProperty="Background.Color" To="#800" /> 
        </Storyboard> 
        </BeginStoryboard> 
       </Trigger.ExitActions> 
       </Trigger> 
      </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
     </Setter> 
    </Style> 
    </Window.Resources> 
    <Grid> 
    <ListBox x:Name="ConnectedDevicesListBox" 
     ItemContainerStyle="{DynamicResource ListboxItemStyle}" > 
     <ListItem/> 
     <ListItem/> 
     <ListItem/> 
     <ListItem/> 
     <ListItem/> 
     <ListItem/> 
     <ListItem/> 
     <ListItem/> 
    </ListBox> 
    </Grid> 
</Window> 

J'ai fait les animations de sortie fanent à une couleur non noire de sorte que vous pouvez voir que le ça se coince après le story-board de sortie IsSelected.

Des idées?

+0

Si vous les échangez, le déclencheur 'sélectionné' est remplacé. Les deux se substituent à eux-mêmes –

Répondre

12

Le comportement par défaut d'un Storyboard est de continuer à définir la valeur de la propriété sur la valeur de la dernière image de l'animation. Voir Animation Tips and Tricks, en particulier la section "Impossible de changer la valeur d'une propriété après l'avoir animée". Vous n'arrêtez jamais les storyboards, donc ils finissent tous par courir et celui qui est déclaré en dernier est en train de définir la valeur finale.

Vous pouvez définir la valeur FillBehavior des Storyboards sur Stop pour que le Storyboard cesse de définir la valeur une fois l'opération terminée. Je pense que vous voudrez le faire sur les storyboards d'ExitActions, mais pas sur les storyboards d'EnterAction, à moins que vous ne définissiez aussi la couleur de fond avec un trigger normal. Quelque chose comme ceci:

<MultiTrigger> 
    <MultiTrigger.Conditions> 
     <Condition Property="IsMouseOver" Value="True" /> 
     <Condition Property="IsSelected" Value="False" /> 
    </MultiTrigger.Conditions> 
    <MultiTrigger.EnterActions> 
     <BeginStoryboard> 
      <Storyboard> 
       <ColorAnimation Duration="0:0:0.15" 
        Storyboard.TargetName="border" 
        Storyboard.TargetProperty="Background.Color" To="#00F" /> 
      </Storyboard> 
     </BeginStoryboard> 
    </MultiTrigger.EnterActions> 
    <MultiTrigger.ExitActions> 
     <BeginStoryboard> 
      <Storyboard FillBehavior="Stop"> 
       <ColorAnimation Duration="0:0:0.3" 
        Storyboard.TargetName="border" 
        Storyboard.TargetProperty="Background.Color" To="#008" /> 
      </Storyboard> 
     </BeginStoryboard> 
    </MultiTrigger.ExitActions> 
</MultiTrigger> 
<Trigger Property="IsSelected" Value="True"> 
    <Trigger.EnterActions> 
     <BeginStoryboard> 
      <Storyboard> 
       <ColorAnimation Duration="0:0:0.15" 
        Storyboard.TargetName="border" 
        Storyboard.TargetProperty="Background.Color" To="#F00" /> 
      </Storyboard> 
     </BeginStoryboard> 
    </Trigger.EnterActions> 
    <Trigger.ExitActions> 
     <BeginStoryboard> 
      <Storyboard FillBehavior="Stop"> 
       <ColorAnimation Duration="0:0:0.3" 
        Storyboard.TargetName="border" 
        Storyboard.TargetProperty="Background.Color" To="#800" /> 
      </Storyboard> 
     </BeginStoryboard> 
    </Trigger.ExitActions> 
</Trigger> 
+0

Merci pour cela, est parfaitement logique. J'ai oublié tout le truc 'FillBehavior' ... depuis un moment que j'ai traité des storyboards (assied gripe: pourquoi, oh pourquoi ils n'ont pas fourni une option' "StopAndHold" 'qui a arrêté le storyboard (comme' Stop') , mais gardé l'état final (comme 'HoldEnd') et en faire la valeur par défaut?). – Alconja

Questions connexes