views:

167

answers:

1

Hi all,

I’m loving behaviours and states in Blend 3. Typically I’m using the GoToStateAction behaviour to go to a state when an action (such as a button click) occurs.

I’ve hit a snag with ControlTemplate triggers though. Blend lets me define states in the ControlTemplate, but I can’t work out how to assign the behaviour to use them.

Here’s my scenario: I’ve created a Style for a RadioButton with a ControlTemplate that contains two Borders (called “Checked” and “Unchecked”) wrapped in a grid. Previously I’ve used a ControlTemplate.Trigger on IsChecked = True to change the opacity of the borders to display the relevant visual. I now want to use state transitions to provide an easing between the two states.

In the ControlTemplate I can create the states IsChecked and IsUnchecked (in a state group called “ChangeCheckState”) as normal. However, there’s nowhere to drag the GoToStateAction to the ControlTemplate.Trigger. Obviously this is doing it wrong.

My only option at this stage is to define my own storyboards to activate when the IsChecked trigger occurs. I really want to just let the state transition handle it for me instead though, because it’s a lot easier to use than getting up to my elbows in storyboard maintenance.

Is there any way to use behaviors to perform the easing for me in this situation?

Here’s some code:

<Style x:Key="MyRadioButton" TargetType="{x:Type RadioButton}">

  <Setter Property="Template">
        <Setter.Value>
              <ControlTemplate TargetType="{x:Type RadioButton}" >

                    <Grid>
                          <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="ChangeCheckState">
                                      <VisualStateGroup.Transitions>
                                            <VisualTransition GeneratedDuration="00:00:00.2000000"/>
                                      </VisualStateGroup.Transitions>
                                      <VisualState x:Name="IsChecked">
                                            <Storyboard>
                                                  <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Checked" Storyboard.TargetProperty="(UIElement.Opacity)">
                                                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                                                  </DoubleAnimationUsingKeyFrames>
                                                  <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="Unchecked" Storyboard.TargetProperty="(UIElement.Opacity)">
                                                        <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                                                  </DoubleAnimationUsingKeyFrames>
                                            </Storyboard>
                                      </VisualState>
                                      <VisualState x:Name="IsUnchecked"/>
                                </VisualStateGroup>
                          </VisualStateManager.VisualStateGroups>
                          <Border x:Name="Checked" Opacity="0" >
                                <!--Content-->
                          </Border>
                          <Border x:Name="Unchecked">
                                <!--Content-->
                          </Border>
                    </Grid>

                    <ControlTemplate.Triggers>
                          <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="Checked" Property="Opacity" Value="1" />
                                <Setter TargetName="Unchecked" Property="Opacity" Value="0" />
                          </Trigger>
                          <Trigger Property="IsChecked" Value="False">
                                <Setter TargetName="Checked" Property="Opacity" Value="0" />
                                <Setter TargetName="Unchecked" Property="Opacity" Value="1" />
                          </Trigger>
                    </ControlTemplate.Triggers>

              </ControlTemplate>
        </Setter.Value>
  </Setter>

A: 

You might be interested in the technique I published on my blog (http://www.livingagile.com/Blog/July-2010/Attaching-Behaviors-from-the-Expression-Blend-SDK-) for assigning behaviors using styles.

Mark Smeltzer
Nice suggestion Mark but in this case it doesn't work. Because the GoToStateAction works in Triggers, I implemented a StylisedTriggers class using the pattern you describe. This compiles fine, but at runtime the GoToStateAction isn't allowed in a StylisedTriggerCollection (type mismatch) because GoToStateAction implements TargetTriggerAction<FrameworkElement> wheras we are expecting TriggerBase (this is what Interaction.GetTriggers returns).I still think I am trying to do this the wrong way.
Zodman