web-dev-qa-db-fra.com

WPF Fade Out sur un contrôle

Dans mon application WPF, j'ai un contrôle de retour que je souhaite voir apparaître à la suite d'une action de l'utilisateur (sauvegarde des données, suppression ...). La visibilité est définie sur Caché pour commencer et le style est défini sur le style animateFadeOut défini en tant que ressource (voir ci-dessous). Ensuite, je souhaite définir le texte et le contrôle de Visibilité sur visibles dans mon code C #, ainsi que le contrôle du retour d’affichage pour afficher le message et disparaître au bout de 5 secondes et rester masqué (Visibility.Hidden).

Le XAML suivant fonctionne la première fois que j'appelle control.Visiblity = Visibility.Visible mais le contrôle ne réapparaît pas la deuxième fois. Je suppose que c'est parce que l'animation est toujours en cours d'exécution, ce qui a le contrôle sur le contrôle des commentaires. J'ai ensuite essayé de régler FillBehavior sur "Stop", mais cela a simplement rendu le contrôle visible à nouveau et je le veux masqué. Ensuite, avec FillBehavior = "Stop", j'ai essayé de définir un déclencheur "lorsque Opacity = 0, définissez la visibilité sur Caché". La gâchette n'a pas semblé se déclencher et je me suis retrouvé avec le contrôle visible une fois de plus après la fin de l'animation.

S'il vous plaît aider à souligner ce que je fais mal ici.

Sinon, si vous pouvez suggérer un meilleur moyen d’afficher un contrôle qui s’efface au bout de 5 secondes et que l’on peut appeler plusieurs fois, j’apprécierais.

Merci!

<Style TargetType="{x:Type FrameworkElement}" x:Key="animateFadeOut">
        <Style.Triggers>
            <Trigger Property="Visibility" Value="Visible">
                <Trigger.EnterActions>
                    <BeginStoryboard >
                        <Storyboard>
                            <DoubleAnimation BeginTime="0:0:5.0" Storyboard.TargetProperty="Opacity"
                         From="1.0" To="0.0" Duration="0:0:0.5"/>
                        </Storyboard>
                    </BeginStoryboard>             
                </Trigger.EnterActions>
            </Trigger>
        </Style.Triggers> 
    </Style>
17
sondlerd

Le problème est que, une fois l’animation terminée, votre contrôle a toujours Visibility = Visible. Vous ne pouvez donc pas le saisir à nouveau.
Je préférerais utiliser une animation qui fait tout, montre d'abord le contrôle, puis le cache.

<Storyboard x:Key="animate">
    <ObjectAnimationUsingKeyFrames BeginTime="0:0:0" Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="0">
            <DiscreteObjectKeyFrame.Value>
                <Visibility>Visible</Visibility>
            </DiscreteObjectKeyFrame.Value>
        </DiscreteObjectKeyFrame>
    </ObjectAnimationUsingKeyFrames>
    <DoubleAnimation BeginTime="0:0:0.0" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.2"/>
    <DoubleAnimation BeginTime="0:0:5.0" Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:0.5"/>
    <ObjectAnimationUsingKeyFrames BeginTime="0:0:5.5" Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="0">
            <DiscreteObjectKeyFrame.Value>
                <Visibility>Hidden</Visibility>
            </DiscreteObjectKeyFrame.Value>
        </DiscreteObjectKeyFrame>
    </ObjectAnimationUsingKeyFrames>
</Storyboard>

Et utilisez-le comme suit: 

((Storyboard)FindResource("animate")).Begin(someControl);
30
alpha-mouse

Liz a raison de dire que la visibilité est toujours visible. La souris alpha est également correcte, vous devez le redéfinir à masqué à un moment donné. Mais cela ne fonctionnera pas si vous le réglez avant la fin de l'animation, comme ceci:

MyControl.Visibility = System.Windows.Visibility.Visible;
MyControl.Visibility = System.Windows.Visibility.Hidden;

parce que les animations ont une priorité plus élevée ( MSDN )

Vous pouvez le redéfinir sur Caché dans l'événement Storyboard.Completed:

private void Show()
    {
        MyControl.Visibility = System.Windows.Visibility.Visible;

        var a = new DoubleAnimation
                    {
                        From = 1.0,
                        To = 0.0,
                        FillBehavior= FillBehavior.Stop,
                        BeginTime = TimeSpan.FromSeconds(2),
                        Duration = new Duration(TimeSpan.FromSeconds(0.5))
                    };
        var storyboard = new Storyboard();

        storyboard.Children.Add(a);
        Storyboard.SetTarget(a, MyControl);
        Storyboard.SetTargetProperty(a, new PropertyPath(OpacityProperty));
        storyboard.Completed += delegate { MyControl.Visibility = System.Windows.Visibility.Hidden; };
        storyboard.Begin();            
    }
15
Kai Wang

Voici mon travail autour. Cela fait apparaître un contrôle en va-et-vient. Au lieu de jouer avec la visibilité, je l'ai traitée en jouant uniquement avec l'opacité.

Merci à Kane de ce billet pour le code original: Fade tout contrôle en utilisant une animation WPF

Storyboard storyboard = new Storyboard();
TimeSpan duration = TimeSpan.FromMilliseconds(500); //

DoubleAnimation fadeInAnimation = new DoubleAnimation() 
    { From = 0.0, To = 1.0, Duration = new Duration(duration) };

DoubleAnimation fadeOutAnimation = new DoubleAnimation()
    { From = 1.0, To = 0.0, Duration = new Duration(duration) };
fadeOutAnimation.BeginTime = TimeSpan.FromSeconds(5);

Storyboard.SetTargetName(fadeInAnimation, element.Name);
Storyboard.SetTargetProperty(fadeInAnimation, new PropertyPath("Opacity", 1));
storyboard.Children.Add(fadeInAnimation);
storyboard.Begin(element);

Storyboard.SetTargetName(fadeOutAnimation, element.Name);
Storyboard.SetTargetProperty(fadeOutAnimation, new PropertyPath("Opacity", 0));
storyboard.Children.Add(fadeOutAnimation);
storyboard.Begin(element);
12
sondlerd

Mon Dieu qui a pris une éternité. Jetez un coup d'oeil à cela, cela résout le problème de l'animation lors de la modification de Visibilité en "Visible" et "Caché" en utilisant l'alpha et l'animation ne gèle pas.

using System.Windows;

namespace WpfApplication4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            button.Visibility = Visibility.Hidden;
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            button.Visibility = Visibility.Visible;
        }
    }
}

XAML:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication4"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.Resources>

            <Style BasedOn="{StaticResource {x:Type Button}}" TargetType="{x:Type Button}">
                <Style.Resources>
                    <Storyboard x:Key="FadeOut">
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" FillBehavior="Stop">
                            <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
                            <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Hidden}"/>
                        </ObjectAnimationUsingKeyFrames>
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:1" AutoReverse="False" />
                    </Storyboard>
                    <Storyboard x:Key="FadeIn">
                        <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:1" AutoReverse="False" />
                    </Storyboard>
                </Style.Resources>
                <Setter Property="Width" Value="120"></Setter>
                <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Visibility" Value="Hidden" />
                            <Condition Property="Opacity" Value="1" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.EnterActions>
                            <StopStoryboard BeginStoryboardName="FadeInStoryboard" />
                            <BeginStoryboard Name="FadeOutStoryboard" Storyboard="{StaticResource FadeOut}" />
                        </MultiTrigger.EnterActions>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Visibility" Value="Visible" />
                            <Condition Property="Opacity" Value="0" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.EnterActions>
                            <StopStoryboard BeginStoryboardName="FadeOutStoryboard" />
                            <BeginStoryboard Name="FadeInStoryboard" Storyboard="{StaticResource FadeIn}" />
                        </MultiTrigger.EnterActions>
                    </MultiTrigger>
                </Style.Triggers>
            </Style>

        </Grid.Resources>
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="200,186,0,0" VerticalAlignment="Top" Width="75" Height="38" />
        <Button x:Name="button1" Content="Hide it" HorizontalAlignment="Left" Margin="112,96,0,0" VerticalAlignment="Top" Width="75" Click="button1_Click"/>
        <Button x:Name="button2" Content="Show it" HorizontalAlignment="Left" Margin="200,96,0,0" VerticalAlignment="Top" Width="75" Click="button2_Click"/>
        <Label x:Name="label" Content="{Binding ElementName=button, Path=Opacity}" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
        <Label x:Name="label1" Content="{Binding ElementName=button, Path=Visibility}" HorizontalAlignment="Left" Margin="10,36,0,0" VerticalAlignment="Top"/>

    </Grid>
</Window>
2
G.Y

Cela devrait réparer votre story-board. 

Cependant, rappelez-vous qu'une fois l'animation terminée, votre contrôle est complètement opaque - invisible, mais votre propriété Visibility est toujours définie sur Visible. Vous devez donc vous assurer que la propriété Visibility est réinitialisée sur masqué ou réduit quelque part également.

<Style TargetType="{x:Type FrameworkElement}" x:Key="animateFadeOut">
         <Style.Triggers>
            <Trigger Property="Visibility" Value="Visible">
               <Trigger.EnterActions>
                  <BeginStoryboard Name="MyFadeEffect">
                     <Storyboard>
                        <DoubleAnimation BeginTime="0:0:5.0" Storyboard.TargetProperty="Opacity"
                         From="1.0" To="0.0" Duration="0:0:0.5"/>
                     </Storyboard>
                  </BeginStoryboard>
               </Trigger.EnterActions>
               <Trigger.ExitActions>
                  <StopStoryboard BeginStoryboardName="MyFadeEffect"/>
               </Trigger.ExitActions>
            </Trigger>
         </Style.Triggers>
      </Style>
0
Liz