Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I change the VisualState of a DataTemplate in a ItemTemplate?

I have some controls in a DataTemplate and I'd like to control it's pressed state behaviour. I did the following where I just put in VisualStateManager in the DataTemplate but it doesn't seem to work. I think it's possible to understand what I'm trying to do below. Is it possible to do it inline inside the DataTemplate tags?

<ItemsControl ItemsSource="{Binding Items}">
    ....
    <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Grid ...>
             <VisualStateManager.VisualStateGroups>
                 <VisualStateGroup x:Name="CommonStates">
                     ...
                     <VisualState x:Name="Pressed">
                         <Storyboard>
                             <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="GridItemBorder">
                                 <DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
                              </ObjectAnimationUsingKeyFrames>
                         </Storyboard>
                     </VisualState>
                 </VisualStateGroup>
             </VisualStateManager.VisualStateGroups>
             <Border x:Name="Border" ...>
                 ...
             </Border>
          </Grid>
      </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
like image 404
xster Avatar asked Nov 22 '12 02:11

xster


1 Answers

The short answer is that there is no "Pressed" visual state for the control type you're targeting -- so while you can reference any state in the Visual State Manager, it won't matter, because the control's code will never put it into that state.

You can see which visual states a control supports by looking at its definition (they're declared using the TemplateVisualState attribute), or by looking at this section on MSDN.

The way to go here might be to use the Button (or an override of [ButtonBase][2] that you write), since that has the "Pressed" visual state built in. You'd just have to write a Control Template for it that provides the layouts/styles that you're after.


Edit Here's an example:

Control template (resources section). This is a control template for the Button control, but it's not really a button. I'm just using it to take advantage of the "Pressed" visual state functionality.

    <ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
        <Grid>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Pressed">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="GridItemBorder">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Border x:Name="GridItemBorder" BorderBrush="Orange" BorderThickness="1" Background="White">
                <ContentPresenter Content="{TemplateBinding Content}" />
            </Border>
        </Grid>
    </ControlTemplate>

Items control

Define the item template as a "Button" which uses the above ControlTemplate.

    <ItemsControl ItemsSource="{Binding SelectedItems}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Template="{StaticResource MyButtonTemplate}" Content="{Binding}" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
like image 171
McGarnagle Avatar answered Sep 20 '22 20:09

McGarnagle