Saturday 23 June 2012

Setting EventTriggers in Blend4

In Blend 3 triggers used to have its own menu which was then replaced in Blend 4 by properties on a behavior.

Because it’s easy to forget here’s a quick screenshot of how to set the event trigger:

image

Assets menu > Behaviors > Add the behaviour > Set the Properties on the behavior

Here is an example of a custom control deriving from control to set a visual state based on an event trigger.

The “SelectionBorder” has its border brush set to null but when then mouse enters it gets set to white.  Mouse leaving event sets it back to it's normal state in the Visual State Manager.

To show a contrast in styles there is also a Storyboard resource activated by the MouseLeftButtonDown event that makes the tile look as though it's been pushed down.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:SilverlightXboxMenu.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Style TargetType="controls:MetroTile">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:MetroTile">
<Border x:Name="SelectionBorder"
Margin="1"
BorderBrush="{x:Null}"
BorderThickness="3"
Cursor="Hand"
RenderTransformOrigin="0.5,0.5">
<Border.Resources>
<Storyboard x:Name="ButtonPressStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="SelectionBorder" Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.GlobalOffsetZ)">
<EasingDoubleKeyFrame KeyTime="0" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="-50">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut" />
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Border.Resources>
<Border.Projection>
<PlaneProjection />
</Border.Projection>
<Border.RenderTransform>
<CompositeTransform />
</Border.RenderTransform>

<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseDown" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectionBorder" Storyboard.TargetProperty="(Border.BorderBrush)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{StaticResource MetroWhiteBrush}" />
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation d:IsOptimized="True"
Duration="0"
Storyboard.TargetName="SelectionBorder"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)"
To="1.03" />
<DoubleAnimation d:IsOptimized="True"
Duration="0"
Storyboard.TargetName="SelectionBorder"
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)"
To="1.03" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="MainContainer" Background="{StaticResource MetroGreenBrush}">

<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter" SourceObject="{Binding ElementName=SelectionBorder}">
<ei:GoToStateAction StateName="MouseOver" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave" SourceObject="{Binding ElementName=SelectionBorder}">
<ei:GoToStateAction StateName="Normal" />
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:ControlStoryboardAction Storyboard="{StaticResource ButtonPressStoryboard}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid x:Name="MainGrid" Background="{Binding Background, RelativeSource={RelativeSource TemplatedParent}}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>

<Image x:Name="PART_DISPLAY_ICON"
Grid.Row="0"
Margin="10,10,10,2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="{Binding DisplayIcon,
RelativeSource={RelativeSource TemplatedParent}}"
Stretch="None" />

<TextBlock x:Name="PART_DISPLAY_TITLE_CONTAINER"
Grid.Row="1"
Margin="10,2,10,10"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
FontFamily="/SilverlightXboxMenu;component/Fonts/Fonts.zip#Segoe UI"
FontSize="16"
Foreground="{StaticResource MetroWhiteBrush}"
Text="{Binding DisplayText,
RelativeSource={RelativeSource TemplatedParent}}"
TextWrapping="Wrap" />
</Grid>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

Another option would have been to derive from button to get visual states up and running then edit from there.


Live Demo


Here’s a live demo, hover over and click the tiles to see the different states:


Source


https://github.com/stevenh77/SilverlightXboxMenu

No comments:

Post a Comment