Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting a guard on a WPF event trigger. Is this possible?

I currently have

<ContentControl
   Grid.Column="2" Grid.Row="3" 
   >
   <ContentControl.Triggers>
       <EventTrigger RoutedEvent="UIElement.MouseEnter">
           <BeginStoryboard 
               Storyboard="{StaticResource ShakeStatorMinorRadiusEdit}"/>
       </EventTrigger>
   </ContentControl.Triggers>

   ... <snip> ...

</ContentControl>

and

    <Grid.Resources>
         <Storyboard x:Key="ShakeStatorMinorRadiusEdit">
            <DoubleAnimationUsingKeyFrames
                        Storyboard.TargetName="StatorMinorRadiusEdit"
                        Storyboard.TargetProperty="RenderTransform.X" 
                        RepeatBehavior="5x"
                        >
                <EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="3"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.15" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.20" Value="-3"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.25" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
     </Grid.Resources>

enter image description here

The idea is that when the mouse enters the yellow highlighted control on the left the yellow highlighted control on the right will shake. The control on the right has the x:Name=StatorMinorRadiusEdit So far so good the above works.

Now I want to add another complication. I only want the animation to trigger if a value on my view model RotorLobes == 1. In an imaginary world I would do.

<ContentControl
   Grid.Column="2" Grid.Row="3" 
   >
   <ContentControl.Triggers>
       <EventTrigger RoutedEvent="UIElement.MouseEnter">

           <If Property="{Binding RotorLobes}" Value="1"/>

           <BeginStoryboard 
               Storyboard="{StaticResource ShakeStatorMinorRadiusEdit}"/>
       </EventTrigger>
   </ContentControl.Triggers>

   ... <snip> ...

</ContentControl>

In the real world I have no idea how to achieve this.

like image 698
bradgonesurfing Avatar asked Aug 08 '13 11:08

bradgonesurfing


People also ask

What is event trigger in WPF?

An event trigger performs some actions when a specific event is fired. It is usually used to accomplish some animation on control such DoubleAnumatio, ColorAnimation, etc. In the following example, we will create a simple button. When the click event is fired, it will expand the button width and height.

How many types of triggers are there in WPF?

Basically, there are 3 types of triggers, they are: Property Trigger. Data Trigger. Event Trigger.


1 Answers

You could try changing from an EventTrigger to a MultiTrigger and using the IsMouseOver property rather than the MouseEnter event. However, as you discovered, Storyboards in styles do not allow you to specify a TargetName, so it's important to move the triggers to the target object.

The example below hard-codes the value of Rotor to 1 and you'll need to correctly namespace the RenderTransform in the TargetProperty or you'll get a runtime exception.

<Grid>
        <Grid.Resources>
            <Storyboard x:Key="ShakeStatorMinorRadiusEdit">
                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="RenderTransform.(TranslateTransform.X)"
                                               RepeatBehavior="5x">
                    <EasingDoubleKeyFrame KeyTime="0:0:0.05"
                                          Value="0" />
                    <EasingDoubleKeyFrame KeyTime="0:0:0.1"
                                          Value="3" />
                    <EasingDoubleKeyFrame KeyTime="0:0:0.15"
                                          Value="0" />
                    <EasingDoubleKeyFrame KeyTime="0:0:0.20"
                                          Value="-3" />
                    <EasingDoubleKeyFrame KeyTime="0:0:0.25"
                                          Value="0" />
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </Grid.Resources>

        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TextBlock Grid.Column="1">Rotor</TextBlock>
        <TextBlock Grid.Column="2">Stator</TextBlock>

        <TextBlock Grid.Column="0"
                   Grid.Row="1">Lobes</TextBlock>
        <TextBlock Grid.Column="0"
                   Grid.Row="2">Major Radius</TextBlock>
        <TextBlock Grid.Column="0"
                   Grid.Row="3">Minor Radius</TextBlock>

        <TextBox Name="RotorLobes"
                 Grid.Column="1"
                 Grid.Row="1"
                 Text="1" />
        <TextBox Grid.Column="1"
                 Grid.Row="2" />
        <TextBox Name="MinorRadiusRotor"
                 Background="Blue"
                 Grid.Column="1"
                 Grid.Row="3" />

        <TextBox Grid.Column="2"
                 Grid.Row="1" />
        <TextBox Grid.Column="2"
                 Grid.Row="2" />
        <TextBox Name="MinorRadiusStator"
                 Background="Green"
                 Grid.Column="2"
                 Grid.Row="3">
            <TextBox.Style>
                <Style>
                    <Style.Triggers>
                        <MultiDataTrigger>
                            <MultiDataTrigger.Conditions>
                                <Condition Binding="{Binding ElementName=MinorRadiusRotor, Path=IsMouseOver}"
                                           Value="True" />
                                <Condition Binding="{Binding ElementName=RotorLobes, Path=Text}}"
                                           Value="1" />
                            </MultiDataTrigger.Conditions>
                            <MultiDataTrigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource ShakeStatorMinorRadiusEdit}" />
                            </MultiDataTrigger.EnterActions>
                        </MultiDataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>

    </Grid>
like image 184
gͫrͣeͬeͨn Avatar answered Oct 20 '22 19:10

gͫrͣeͬeͨn