Windows Phone from Scratch #13 — Custom Behaviors Part II: ActionTrigger

In the previous mini-tutorial you saw how to create a custom Behavior, and in that trigger_stock custom behavior you captured the on click action event of the button.  This pattern is so common that there is a special type of behavior, an ActionTrigger to simplify coding a custom behavior the responds to an event. 

Rather than writing an OnAttached method in which you capture the event, and an OnDetaching method in which you remove the event handler, the ActionTrigger assumes you want to capture an event, and requires only that you provide an Invoke method that will be called when the event is fired.

To see this, return to Reverse.cs and modify the ReverseAction so that it derives from TriggerAction rather than from Behavior

protected override void Invoke( object parameter )

Next, you can remove the entire contents of OnAttached and OnDetaching and replace them with the following

protected override void Invoke( object parameter )
{
   var currentContents = AssociatedObject.Content.ToString();
   var newStringBuilder = new StringBuilder();
   for ( var i = currentContents.Length - 1;         
         i >= 0;
         i-- )
   {
      newStringBuilder.Append( currentContents[ i ] );
   }
   AssociatedObject.Content =
           newStringBuilder.ToString();
}

Notice that the body of Invoke is identical to the code that was previously in the AssociatedObject_Click event handler. 

Save this in Visual Studio and switch back to Blend.  Remove the Behavior currently associated with the Button (you may be forced to do this in Xaml) and then drag the revised behavior on to the button.  Notice in the proprerties window that the Click event is the default (but not the only) event that you can associate with this behavior.

That’s it! Your custom behavior now works as expected, and is much simpler to maintain.

The Xaml

Before you close the application, steal a look at the Xaml that you’ve generated in MainPage.Xaml for the trigger:

<Button Content="Button" Grid.Column="1" 
        Margin="89,8,73,1" Grid.Row="4">
    <Custom:Interaction.Triggers>
        <Custom:EventTrigger EventName="Click">
            <local:ReverseAction/>
        </Custom:EventTrigger>
    </Custom:Interaction.Triggers>

Note that on line 4 the EventName that will cause the Invoke method to run is specified as a parameter.  This is just how the “built in” behaviors work, as you can see earlier in the Xaml file where the Events for changing state were created in response to your dragging on the GoToState Behavior,

<RadioButton x:Name="Male" Content="Male" 
             HorizontalAlignment="Left" 
             VerticalAlignment="Bottom" 
             Margin="5" IsChecked="True" 
             GroupName="Sex">
    <Custom:Interaction.Triggers>
        <Custom:EventTrigger EventName="Click">
            <ic:GoToStateAction TargetName="OK" StateName="Dirty"/>
        </Custom:EventTrigger>
    </Custom:Interaction.Triggers>
</RadioButton>

About Jesse Liberty

Jesse Liberty has three decades of experience writing and delivering software projects and is the author of 2 dozen books and a couple dozen online courses. His latest book, Building APIs with .NET will be released early in 2025. Liberty is a Senior SW Engineer for CNH and he was a Senior Technical Evangelist for Microsoft, a Distinguished Software Engineer for AT&T, a VP for Information Services for Citibank and a Software Architect for PBS. He is a Microsoft MVP.
This entry was posted in Patterns & Skills. Bookmark the permalink.