Трудно точно понять, в чем проблема, не видя остальной части кода, но я предполагаю, что это связано с начальными значениями анимированных свойств.
Я реализовал пользовательский элемент управления в WPFс прямоугольником внутри окна просмотра и использовали триггеры + раскадровки из вопроса, чтобы увидеть эффект.Действительно, моя первая попытка не исчезла и не исчезла.
Что я сделал, чтобы решить ее, так это указав From
значения в анимации, чтобы они работали независимо от того, каково было первоначальное значение DP:
<DoubleAnimation BeginTime="00:00:00"
Duration="00:00:00.5"
Storyboard.TargetName="MyViewBoxje"
Storyboard.TargetProperty="Opacity"
From="0"
To="1" />
Обратите внимание From="0"
на вышеприведенную анимацию.Конечная раскадровка была изменена таким же образом, чтобы перейти от 1 к 0.
Для полноты я установил непрозрачность на 0
и для определения элемента viewbox внутри ControlTemplate.
Вот полный исходный код для соответствующих частей.Элемент управления является стандартным пользовательским элементом управления WPF, унаследованным от Control .У него есть одно свойство зависимости, называемое IsLoading
(bool
), которое по умолчанию равно false
:
public bool IsLoading
{
get { return (bool)GetValue(IsLoadingProperty); }
set { SetValue(IsLoadingProperty, value); }
}
// Using a DependencyProperty as the backing store for IsLoading. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsLoadingProperty =
DependencyProperty.Register("IsLoading", typeof(bool), typeof(LoadingControl), new UIPropertyMetadata(false));
ControlTemplate - определено в generic.xaml в стиле для {x:Type local:LoadingControl}
<ControlTemplate TargetType="{x:Type local:LoadingControl}">
<ControlTemplate.Triggers>
<Trigger Property="IsLoading" Value="True">
<Trigger.EnterActions>
<RemoveStoryboard BeginStoryboardName="EndAnimateLoadingCanvas" />
<BeginStoryboard Name="AnimateLoadingCanvas">
<Storyboard FillBehavior="Stop">
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MyViewBoxje"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation BeginTime="00:00:00"
Duration="00:00:00.5"
Storyboard.TargetName="MyViewBoxje"
Storyboard.TargetProperty="Opacity"
From="0"
To="1" />
<DoubleAnimation BeginTime="00:00:00"
Duration="00:00:02"
Storyboard.TargetName="AnimatedRotateTransform"
Storyboard.TargetProperty="Angle"
From="360"
To="0"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="AnimateLoadingCanvas" />
<BeginStoryboard Name="EndAnimateLoadingCanvas">
<Storyboard FillBehavior="Stop">
<DoubleAnimation BeginTime="00:00:00"
Duration="00:00:00.5"
Storyboard.TargetName="MyViewBoxje"
Storyboard.TargetProperty="Opacity"
From="1"
To="0" />
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00.5"
Storyboard.TargetName="MyViewBoxje"
Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Viewbox x:Name="MyViewBoxje" Opacity="0">
<!-- BG with 0x50 alpha so that it's translucent event at 100% visibility -->
<Grid Width="100" Height="100" Background="#50000000">
<Rectangle Width="70" Height="20" Fill="Green" Stroke="Black" StrokeThickness="2" RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<RotateTransform Angle="360" x:Name="AnimatedRotateTransform" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</Viewbox>
</Border>
</ControlTemplate>
Я использовал в своем главном окне примерно так:
<Grid x:Name="LayoutRoot">
<!-- All other stuff here ... -->
<my:LoadingControl IsLoading="{Binding IsLoading}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Grid>
И чтобы проверить это, у меня была ViewModel со свойством IsLoading
, которое установлено как DataContext для основногоокно.И в конструкторе ViewModel я устанавливаю IsLoading
в true и затем запускаю таймер, который переключает значение свойства каждые 5 секунд:
public MainWindowViewModel()
{
IsLoading = true;
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromSeconds(5);
t.Tick += (s, e) => IsLoading = !IsLoading;
t.Start();
}