15

I have a label that I only make visible based on one of my ViewModel Properties. Here is the XAML:

<Label  HorizontalAlignment="Center" VerticalAlignment="Center"
        HorizontalContentAlignment="Center" 
        VerticalContentAlignment="Center" 
        FontSize="24" Width="200" Height="200" >
    <Label.Content >
        Option in the money! 
    </Label.Content>
    <Label.Style>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding OptionInMoney}" Value="True">
                    <Setter Property="Visibility"
                Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Label.Style>

</Label>

I'm not sure this is the best way, but in any case, I'd also like to have the label flashing. Clearly, I only want it flashing when it is visible. Can someone point me to some example code, or write a quick example to do this? I assume I need some sort of trigger, and an animation. Presumably I also need a trigger when the label is no longer visible so that I stop the animation?

Thanks, Dave P.S. Is there a good book or site for all these WPF tricks? Something like the "MFC Answer Book" for those that remember that book.

Agustin Meriles
  • 4,866
  • 3
  • 29
  • 44
Dave
  • 8,095
  • 14
  • 56
  • 99
  • Hah - options trading system? :) Are you familiar with storyboard animations? You could get the behavior you're after by animating the Opacity property on the element - if I get a chance I'll put up an example. – JerKimball Apr 04 '13 at 22:08

3 Answers3

44

You could add a Storyboard animation to the Style.Resources and start it in the EnterActions section of the DataTrigger.

A simple DoubleAnimation on the Opacity should work fine

Something like this:

<Label.Style>
    <Style TargetType="{x:Type Label}">
        <Style.Resources>
            <Storyboard x:Key="flashAnimation" >
                <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" AutoReverse="True" Duration="0:0:0.5" RepeatBehavior="Forever" />
            </Storyboard>
        </Style.Resources>

        <Setter Property="Visibility" Value="Hidden" />
        <Style.Triggers>
            <DataTrigger Binding="{Binding OptionInMoney}" Value="True">
                <Setter Property="Visibility" Value="Visible" />
                <DataTrigger.EnterActions>
                    <BeginStoryboard Name="flash" Storyboard="{StaticResource flashAnimation}" />
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="flash"/>
                </DataTrigger.ExitActions>
            </DataTrigger>

        </Style.Triggers>
    </Style>
</Label.Style>
sa_ddam213
  • 42,848
  • 7
  • 101
  • 110
  • 1
    Fantastic! Do I need to arrange to stop the animation when the property(OptionInMoney) goes back to false, or will that happen automatically. I.e. do I need a DataTrigger.ExitActions and if so, how do I set that up? I mention it, because I saw some discussion in other posts of the animation continuing forever even though it's not visible. Thanks again. – Dave Apr 05 '13 at 07:21
  • 1
    yes, It's probably a good idea to stop the animation in `ExitActions`, I have updated the answer with the `StopStoryboard` – sa_ddam213 Apr 05 '13 at 07:35
4

StoryBoard is certainly the WPF way, but it can be achieved by a simple code also. Here it goes, to make a label background blink:

lblTimer is a Lebel on your form with some text, say, "I AM BLINKING"

This can be applied to any property, as VISIBILITY.

// Create a timer.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    DispatcherTimer timer = new DispatcherTimer();
    timer.Tick += timer_Tick;
    timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
    timer.Start();
}

// The timer's Tick event.
private bool BlinkOn = false;
private void timer_Tick(object sender, EventArgs e)
{
    if (BlinkOn)
    {
        lblTimer.Foreground = Brushes.Black;
        lblTimer.Background = Brushes.White;
    }
    else
    {
        lblTimer.Foreground = Brushes.White;
        lblTimer.Background = Brushes.Black;
    }
    BlinkOn = !BlinkOn;
}
NishantM
  • 141
  • 12
  • 1
    Worked well, I use opacity to flicker with a Visibility.Collapsed when use opts to dismiss the flicker element(s) +1 – BENN1TH Sep 09 '17 at 10:41
2

Try this post. It's called 'Blinking TextBlock' but you can easily swap a TextBox for a Label`.

Community
  • 1
  • 1
Sheridan
  • 68,826
  • 24
  • 143
  • 183