MVVM pattern design is very powerful, but it is also very complex. This is the main feature of this approach, where UI and business logic are splitted: you will love this feature, but sometimes, you will hate it, because it makes harder all the simply UI operation (also the message box… you can use them, but if you want a 100% MVVM application, you can’t).

In this post I will show you how to make an image blinking from the ViewModel, simply changing the value of a boolean variable.

In my case, I have this xaml code:

<Button Style="{DynamicResource BtnToolBar}" Command="{Binding refreshAll}">
    <Image x:Name="imgRicalcola" Style="{DynamicResource ImageStyleRicalcola}" ToolTip="{StaticResource UpdateData}"/>
</Button>

As you can see, I’m using the Style property, but you can also use the inner tag Image.Style:

<Image Source="../Resources/btn_blu_Ricalcola_50_disabled.png" >
  <Image.Style>
     <Style>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Property1}" Value="true">
          <DataTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource BlinkingAnimation}" x:Name="blink"/>
          </DataTrigger.EnterActions>
          <DataTrigger.ExitActions>
            <StopStoryboard BeginStoryboardName="blink" />
          </DataTrigger.ExitActions>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Image.Style> 
</Image> 

In one way or another, the Style will be our key to the success.

I have used my Style for this element. The most important part in the code below is the one between the tag DataTrigger

Here my style, but I repeat: the following code snippet, can be replaced by the previous. DON’T USE BOTH OF THEM!

    <Style x:Key="ImageStyleRicalcola" TargetType="{x:Type Image}">
        <Setter Property="Source" Value="../Resources/btn_blu_Ricalcola_50_disabled.png"/>
        <Setter Property="FlowDirection" Value="LeftToRight"/>
        <Setter Property="Height" Value="50"/>
        <Setter Property="Width" Value="57"/>
        <Setter Property="Stretch" Value="None"/>
        <Style.Triggers>

            <Trigger Property="IsEnabled" Value="true">
                <Setter Property="Source" Value="../Resources/btn_blu_Ricalcola_50.png"/>
            </Trigger>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsMouseOver" Value="True"/>
                    <Condition Property="IsEnabled" Value="True"/>
                </MultiTrigger.Conditions>
                <Setter Property="Source" Value="../Resources/btn_blu_Ricalcola_50_hover.png"/>
            </MultiTrigger>
            <DataTrigger Binding="{Binding IsBlinking}" Value="true">
                <DataTrigger.EnterActions>
                    <BeginStoryboard Storyboard="{StaticResource MyBlinkingAnimation}" x:Name="blink"/>
                </DataTrigger.EnterActions>
                <DataTrigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="blink" />
                </DataTrigger.ExitActions>
            </DataTrigger>
        </Style.Triggers>
    </Style>

You have also to add this Resource, in the same place where you have written the previous code snippet (I use a separated xaml for set my resources). This is used for define your animation. In this case, playing with the Opacity, we create a blinking effect.

<Storyboard x:Key="MyBlinkingAnimation">
    <DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)" BeginTime="0:0:0" Duration="0:0:0.5" From="1.0" To="0.5" RepeatBehavior="Forever" AutoReverse="True"/>
</Storyboard>

Finally, you only have to create a bool variable in you viewModel called isBlinking. When it is set to True, the image will blink. Set it again to false to stop the blinking effect.

Advertisements