WPF Fade Out на контроле
В моем приложении WPF у меня есть элемент управления с обратной связью, который я хочу появиться после завершения действия пользователя (сохранить данные, удалить...). Для видимости установлено значение Скрытый для начала, а стиль - стиль animateFadeOut, определенный как ресурс (см. Ниже). Затем я хочу установить текст и управлять видимостью видимым в моем коде на С#, а управление обратной связью отображает сообщение и исчезает через 5 секунд и остается скрытым (Visibility.Hidden).
Следующий XAML работает при первом вызове control.Visiblity = Visibility.Visible, но элемент управления не появляется снова во второй раз. Я полагаю, что это связано с тем, что анимация все еще работает, и она контролирует контроль обратной связи. Затем я попытался установить FillBehavior на "Stop", но это снова заставило элемент управления увидеть снова, и я хочу, чтобы он был скрыт. Затем, с помощью FillBehavior = "Стоп", я попытался установить триггер "когда Opacity = 0, установите видимость в скрытую". Триггер, похоже, не срабатывал, и я снова остался с видимым контролем после завершения анимации.
Пожалуйста, помогите указать, что я делаю неправильно здесь.
В качестве альтернативы, если вы можете предложить лучший способ отображения элемента управления, который исчезает через 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>
Ответы
Ответ 1
Проблема заключается в том, что после завершения анимации ваш элемент управления по-прежнему имеет видимость = видимый, поэтому его нельзя ввести снова.
Я бы предпочел использовать анимацию, которая выполняет все это, сначала показывает элемент управления, а затем скрывает его.
<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);
Ответ 2
Лиз верна, что видимость все еще видима. альфа-мышь также правильна, что вам нужно вернуть ее в Hidden в какой-то момент. Но это не сработает, если вы установите его до того, как анимация будет завершена следующим образом:
MyControl.Visibility = System.Windows.Visibility.Visible;
MyControl.Visibility = System.Windows.Visibility.Hidden;
потому что анимации имеют более высокий приоритет (MSDN)
Вы можете установить его обратно в Hidden in Storyboard.Completed event:
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();
}
Ответ 3
Вот моя работа. Это снова затухает контроль и возвращается. Вместо того, чтобы играть с Видимостью, я обработал ее, играя только с непрозрачностью.
Спасибо Кейну из этого поста для оригинального кода: Потерять любой элемент управления с помощью анимации 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);
Ответ 4
Бог мой, который навсегда. Взгляните на это, он решает, что проблема анимации изменений Видимости в "Видимый" и "Скрытый" с использованием альфы, а анимация не будет зависеть.
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>
Ответ 5
Это должно исправить вашу раскадровку.
Однако помните, что как только анимация будет завершена, ваш элемент управления будет полностью непрозрачным - невидим, но свойство Visibility по-прежнему настроено на Visible. Таким образом, вы должны будете убедиться, что свойство Видимость reset скрыто или свернуто где-то тоже.
<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>