WPF Fade Out на элементе управления - PullRequest
17 голосов
/ 30 ноября 2010

В моем приложении WPF у меня есть элемент управления обратной связи, который я хочу отобразить после завершения действия пользователя (сохранение данных, удаление ...).Для видимости задано значение Hidden для начала, а для стиля - стиль animateFadeOut, определенный как ресурс (см. Ниже).Затем я хочу, чтобы текст и элемент управления Visibility были видны в моем коде C #, чтобы элемент управления обратной связи отображал сообщение, исчезал через 5 секунд и оставался скрытым (Visibility.Hidden).

Следующий XAML работаетв первый раз я вызываю control.Visiblity = Visibility.Visible, но элемент управления не появляется снова во второй раз.Я полагаю, что это потому, что анимация все еще работает, которая контролирует контроль обратной связи.Затем я попытался установить FillBehavior на «Стоп», но это просто снова сделало элемент управления видимым, и я хочу, чтобы он был скрыт.Затем, с FillBehavior = "Stop", я попытался установить триггер "когда Opacity = 0, установите Visibility в Hidden".Похоже, что триггер не сработал, и после завершения анимации у меня остался видимый элемент управления.

Пожалуйста, помогите указать, что я здесь делаю неправильно.

В качестве альтернативы, если выЯ могу предложить лучший способ отображения элемента управления, который исчезает через 5 секунд и может вызываться снова и снова, я был бы признателен.

Спасибо!

<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>

Ответы [ 5 ]

31 голосов
/ 30 ноября 2010

Проблема в том, что после завершения анимации ваш элемент управления по-прежнему имеет Visibility = Visible, поэтому его нельзя ввести снова.
Я бы предпочел использовать анимацию, которая делает все это, сначала показывает элемент управления, а затем скрывает его.

<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>

И используйте его следующим образом:

((Storyboard)FindResource("animate")).Begin(someControl);
15 голосов
/ 30 ноября 2010

Лиз права, что Visibility все еще видна.Альфа-мышь также правильна, что вам нужно установить ее обратно в Hidden в какой-то момент.Но это не сработает, если вы установите его обратно до завершения анимации следующим образом:

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

, поскольку анимация имеет более высокий приоритет ( MSDN )

Вы можетеустановите его обратно в Скрытое в Storyboard. Завершенное событие:

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();            
    }
12 голосов
/ 30 ноября 2010

Вот моя работа вокруг.Это затухает контроль в и обратно.Вместо того, чтобы играть с видимостью, я работал с ней только с непрозрачностью.

Спасибо Кейну из этого поста за оригинальный код: Исчезаем любой элемент управления с помощью анимации 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);
2 голосов
/ 18 октября 2016

Боже мой, что взял навсегда.Взгляните на это, оно решает проблему анимации при изменении видимости на «Видимый» и «Скрытый» с использованием альфы, и анимация не останавливается.

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>
0 голосов
/ 30 ноября 2010

Это должно исправить вашу раскадровку.

Однако помните, что после завершения анимации ваш элемент управления становится полностью непрозрачным - невидимым, но для свойства Visibility по-прежнему установлено значение Visible. Поэтому вам нужно убедиться, что свойство Visibility также сброшено или где-то свернуто.

<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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...