How to trigger an animation when a label changes a value in WPF?

I apologize for this trivial question, I'm new to WPF and keep looking for blogs that almost describe what I want ...

I have a shortcut attached to a property that updates beautifully on the screen, and now I need a little animation that blinks the background color of the label whenever the value is updated. Ideally I would like a clean xaml solution

I looked at DataTriggers, but they seem to require an equality condition, and EventTriggers cannot seem to be tied to any data mapping events.

thanks Oskar

+3
source share
3 answers

, . Content . , , "True" "False", , 2 . Cnverter Tag , Name . , RouterEvents xaml.

public class TestConverter : IValueConverter
{
    private string  _originalValue = String.Empty;
    private bool    _previousValue = false;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        _originalValue = (string)value;
        _previousValue = !_previousValue;
        return _previousValue.ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return _originalValue;
    }
}

:

label1.DataContext = new Test() { Name = DateTime.Now.ToString() };

XAML:

<Window.Resources>
    <local:TestConverter x:Key="TestConverter" />
</Window.Resources>
<Grid>
    <Label             
        Height="28" 
        HorizontalAlignment="Left" 
        Margin="132,96,0,0" 
        Name="label1" VerticalAlignment="Top" Width="120">

        <Label.Content>
            <Binding Path="Name"/>
        </Label.Content>
        <Label.Tag>
            <Binding Path="Name" Converter="{StaticResource TestConverter}"/>
        </Label.Tag>
        <Label.Background>
            <SolidColorBrush x:Name="animatedBrush1" Color="Yellow" />
        </Label.Background>
        <Label.Style>
            <Style TargetType="Label">
                <Style.Triggers>
                    <Trigger Property="Tag" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard AutoReverse="True">
                                    <!--<DoubleAnimation 
                                        Storyboard.TargetProperty="FontSize" To="20"/>-->
                                    <DoubleAnimation 
                                        Storyboard.TargetProperty="Opacity" To="0.0" AutoReverse="True"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                    <Trigger Property="Tag" Value="False">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard AutoReverse="True">
                                    <DoubleAnimation 
                                        Storyboard.TargetProperty="FontSize" To="20"/>
                                    <!--"<DoubleAnimation 
                                        Storyboard.TargetProperty="Opacity" To="0.0" AutoReverse="True"/>-->
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Label.Style>
        <Label.Triggers>
            <EventTrigger RoutedEvent="Label.MouseEnter">
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="animatedBrush1"
                            Storyboard.TargetProperty="Color"
                            To="Blue" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
            <EventTrigger RoutedEvent="Label.MouseLeave">
                <BeginStoryboard>
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="animatedBrush1"
                            Storyboard.TargetProperty="Color"
                            To="Yellow" Duration="0:0:1" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Label.Triggers>
    </Label>
</Grid>

, ,

+2

? NotifyOnTargetUpdated=True , .

<DataTemplate>
    <Border Name="templateBorder">
        <TextBlock Text="{Binding Path=Name, NotifyOnTargetUpdated=True}" />
    </Border>
    <DataTemplate.Triggers>
        <EventTrigger RoutedEvent="Binding.TargetUpdated">
            <BeginStoryboard>
                <Storyboard AutoReverse="True">
                    <DoubleAnimation Storyboard.TargetProperty="Opacity" 
                                     To=".1" Duration="0:0:.5" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </DataTemplate.Triggers>
</DataTemplate>
+7

I liked the answer of serge_gubenko, but I thought I should mention another technique that I sometimes use. Serge's answer is closer to your "pure XAML" ideal, because it only has a converter, but this answer has less code and can be more readable. There he is:

Add the ChangedCallback property to your Name property and open the storyboard:

DependencyProperty NameProperty = DependencyProperty.Register( ..., new UIElementMetadata
{
  PropertyChangedCallback = (obj, e) =>
  {
    storyBoard.Begin();
  }
});

If you do not need a flash when the window loads first, you can add a flag:

...
  PropertyChangedCallback = (obj, e) =>
  {
    if(_initialized)
      storyBoard.Begin();
  }
...

protected override void OnInitialized(...)
{
  _initialized = true;
}
+2
source

Source: https://habr.com/ru/post/1726818/


All Articles