Customize UXFlow Appearance Based on Item Position
The latest ClientUI release (2011 R2 SP1) introduces several enhancements for UXFlow control. Some of the significant enhancements are the new AutoReflection property and PositionStates visual states. They are introduced to set different styles in UXFlowItem according to its position.
The new PositionStates enhancement enables you to customize the layout and appearance of the item based on the flow position. See the following illustration.
In this blog, I’m going to share how to achieve the above scenario in a step-by-step walkthrough.
1. Put additional text to the UXFlowItem.
You will need Microsoft Expression Blend to edit the ItemContainerStyle of the UXFlow control.
After the generated template is shown, put the text in CoverElementPerspective. CoverElementPerspective contains the ImageLoader of UXFlowItem. That’s the reason why the text requires to be put in that element. In this case, TextBlock is used as the text.
To easily maintain the layout, let’s use Grid and StackPanel container with configuration as shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<Intersoft:ContentPerspective x:Name="CoverElementPerspective" AutoRefresh="False" EnableReflection="{TemplateBinding EnableReflection}" VerticalContentAlignment="Bottom"> <Border Background="Silver" BorderBrush="#8D8D8D" BorderThickness="2" CornerRadius="8"> <StackPanel> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Intersoft:ContentTransformer x:Name="ContentTransformer" Grid.ColumnSpan="2"> <TextBlock Text="{Binding Contact.Name}" FontSize="24" Margin="4" HorizontalAlignment="Center"/> </Intersoft:ContentTransformer> <Intersoft:ImageLoader Grid.Row="1" Grid.Column="1" ImageStretch="None" x:Name="CoverElementImage" AutoSyncPerspectiveReflection="False" ImageSource="{TemplateBinding ImageSource}" ProgressBarHorizontalAlignment="Stretch" ProgressBarVerticalAlignment="Bottom" ProgressTextVisibility="Collapsed" ProgressBarMargin="15,0,15,15"/> </Grid> <StackPanel x:Name="info" > <TextBlock Text="{Binding Contact.Email}" TextAlignment="Center" FontSize="10" /> <TextBlock Text="{Binding Contact.Twitter}" TextAlignment="Center" FontSize="10"/> </StackPanel> </StackPanel> </Border> </Intersoft:ContentPerspective> |
2. Implement the visual state and switch the position by using PositionStates in VisualStateGroup.
As stated before, PositionStates is available only in the SP1 release.
1 2 3 4 5 |
<VisualStateGroup x:Name="PositionStates"> <VisualState x:Name="LeftSide"/> <VisualState x:Name="Center"/> <VisualState x:Name="RightSide"/> </VisualStateGroup> |
The PositionStates is automatically generated after you use EditItemContainer template.
Center is the default state when an item is selected. Therefore, you only need to customize position, animations and styles for the LeftSide and RightSide.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
<VisualStateGroup x:Name="PositionStates"> <VisualState x:Name="LeftSide"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Transform)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <CompositeTransform Rotation="-90"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Margin)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0" Value="20,20,0,20"> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <System:Int32>1</System:Int32> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <System:Int32>2</System:Int32> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="info"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Center"/> <VisualState x:Name="RightSide"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Transform)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <CompositeTransform Rotation="90"/> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Margin)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0" Value="0,20,20,20"> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <System:Int32>2</System:Int32> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <System:Int32>1</System:Int32> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="ContentTransformer"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <System:Int32>2</System:Int32> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="info"> <DiscreteObjectKeyFrame KeyTime="0"> <DiscreteObjectKeyFrame.Value> <Visibility>Collapsed</Visibility> </DiscreteObjectKeyFrame.Value> </DiscreteObjectKeyFrame> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> |
3. Set AutoRefreshReflection to true.
When using the default UXFlow configuration, the reflection will be automatically cached. This may cause a reflection issue while switching the styles. To avoid this issue, simply set AutoRefreshReflection to true.
You can also download the sample project for your references.
I hope this post can give you some insights about styling with UXFlow control. As usual, feedback and comments are always welcome.
Warm Regards,
Handy