Animated DockListBox
I am building a ListBox that represents Dock positions (looks like an iPod wheel) and want to animate is so the selected dock position rotates from the old value to the new position. My XAML is below. The strage behavior is that it works fine for some of the transitions but for others it jumps back to start at the default (left). Any help would be appreciated.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:ctl="clr-namespace:System.Windows.Controls;assembly=PresentationFramework"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"><!-- Data Providers -->
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="DockValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="Dock" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider><!-- Brushes -->
<LinearGradientBrush x:Key="ArrowFillBrush"
EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="#A5224422"
Offset="0" />
<GradientStop Color="#CC668866"
Offset="0.25" />
<GradientStop Color="#FF557755"
Offset="1" />
</LinearGradientBrush><RadialGradientBrush x:Key="MouseOverFillBrush">
<GradientStop Color="#FFB9B9B9"
Offset="0.821" />
<GradientStop Color="#FF666666"
Offset="1" />
<GradientStop Color="#FFFFFFB8"
Offset="0.6" />
</RadialGradientBrush><LinearGradientBrush x:Key="SelectedArrowBrush"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FFF70B0B"
Offset="0" />
<GradientStop Color="#FF480C0C"
Offset="1" />
</LinearGradientBrush><RadialGradientBrush x:Key="InnerEllipseBrush"
GradientOrigin="0.245,0.302">
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5"
CenterY="0.5"
ScaleX="0.896"
ScaleY="0.788" />
<SkewTransform AngleX="0"
AngleY="0"
CenterX="0.5"
CenterY="0.5" />
<RotateTransform Angle="16.192"
CenterX="0.5"
CenterY="0.5" />
<TranslateTransform X="0.017"
Y="-0.078" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#FFE0E0E0"
Offset="0" />
<GradientStop Color="#FF727272"
Offset="1" />
</RadialGradientBrush><RadialGradientBrush x:Key="OuterEllipseBrush">
<GradientStop Color="#FFB9B9B9"
Offset="0.821" />
<GradientStop Color="#FF666666"
Offset="1" />
<GradientStop Color="#FFFFFFFF"
Offset="0.464" />
</RadialGradientBrush><!-- Dock Arrow -->
<Style x:Key="DockArrow"
TargetType="Label">
<Setter Property="Height"
Value="14" />
<Setter Property="Width"
Value="14" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Path Stroke="Transparent"
Fill="{StaticResource SelectedArrowBrush}"
StrokeThickness="1">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True"
StartPoint="7,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="0,14" />
<LineSegment Point="14,14" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style><Style x:Key="RotorBorderStyle"
TargetType="{x:Type ctl:Border}">
<Setter Property="Width"
Value="70" />
<Setter Property="Height"
Value="70" />
<Setter Property="ClipToBounds"
Value="True" />
<Setter Property="RenderTransformOrigin"
Value="0.5,0.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="0" />
</Setter.Value>
</Setter>
</Style><!-- DataTemplate -->
<DataTemplate x:Key="ArrowTemplate">
<Path x:Name="ArrowPath"
Stroke="Transparent"
StrokeThickness="1"
Fill="{Binding Path=Tag, RelativeSource={RelativeSource TemplatedParent}}"
DockPanel.Dock="{TemplateBinding DockPanel.Dock}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True"
StartPoint="7,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="0,14" />
<LineSegment Point="14,14" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</DataTemplate><!-- ListBoxItem -->
<Style x:Key="Arrow"
TargetType="ListBoxItem">
<Setter Property="Height"
Value="14" />
<Setter Property="Width"
Value="14" />
<Setter Property="Background"
Value="{StaticResource ArrowFillBrush}" />
<Setter Property="DockPanel.Dock"
Value="{Binding RelativeSource={RelativeSource Self}, Path=Content}" />
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="VerticalContentAlignment"
Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<ContentPresenter SnapsToDevicePixels="True"
Tag="{TemplateBinding Background}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
Value="#FF323200" />
</Trigger>
<Trigger Property="DockPanel.Dock"
Value="Left">
<Setter Property="Margin"
Value="1.5,28,-1.5,0" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="270" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="DockPanel.Dock"
Value="Right">
<Setter Property="Margin"
Value="12.5,-6.5,-12.5,6.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="90" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="DockPanel.Dock"
Value="Top">
<Setter Property="Margin"
Value="-6.5,1.5,6.5,-1.5" />
</Trigger>
<Trigger Property="DockPanel.Dock"
Value="Bottom">
<Setter Property="Margin"
Value="13.5,33.5,-13.5,-33.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="180" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style><!-- ListBox -->
<Style x:Key="DockListBoxStyle"
TargetType="{x:Type ListBox}">
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Width"
Value="70" />
<Setter Property="Height"
Value="70" />
<Setter Property="ItemsSource"
Value="{Binding Source={StaticResource DockValues}}" />
<Setter Property="ItemContainerStyle"
Value="{StaticResource Arrow}" />
<Setter Property="ItemTemplate"
Value="{StaticResource ArrowTemplate}" />
<Setter Property="SelectedIndex"
Value="3" /><!-- ItemsPanel -->
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<DockPanel x:Name="DockListBoxDockPanel"
Height="70"
Width="70" />
</ItemsPanelTemplate>
</Setter.Value>
</Setter><!-- Control Template -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Grid x:Name="DockListBoxLayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="0.2*" />
<RowDefinition Height="0.6*" />
<RowDefinition Height="0.2*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.6*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Ellipse x:Name="DockListBoxOuterEllipse"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="0"
Grid.RowSpan="3"
Stroke="Transparent"
StrokeThickness="0"
Fill="{StaticResource OuterEllipseBrush}">
<Ellipse.Effect>
<DropShadowEffect Color="#AF777777"
Direction="300" />
</Ellipse.Effect>
</Ellipse>
<Ellipse Name="DockListBoxInnerEllipse"
Grid.Column="1"
Grid.Row="1"
Fill="{StaticResource InnerEllipseBrush}" />
<TextBlock Name="DockListBoxLabel"
Grid.Column="1"
Grid.Row="1"
VerticalAlignment="Center"
TextAlignment="Center"
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=SelectedValue, StringFormat=Dock \{0\}}"
TextWrapping="Wrap"
Padding="2"
FontSize="10"
Foreground="Black"
FontWeight="Bold" /><DockPanel x:Name="DockListBoxDockPanel"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="0"
Grid.RowSpan="3">
<ItemsPresenter SnapsToDevicePixels="True"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}" />
</DockPanel><!-- Animated Rotor -->
<ctl:Grid x:Name="RotorGrid"
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="0"
Grid.RowSpan="3">
<ctl:Border x:Name="RotorBorder"
Width="70"
Height="70"
ClipToBounds="True"
RenderTransformOrigin="0.5, 0.5">
<ctl:Border.RenderTransform>
<RotateTransform x:Name="RotorBorderRotateTransform" />
</ctl:Border.RenderTransform>
<ctl:Grid>
<ctl:Label Style="{StaticResource DockArrow}"
Width="14"
Height="14"
Focusable="True"
Tag="0"
Margin="1"
x:Name="DockMarker"
d:LayoutOverrides="Height"
VerticalAlignment="Top"
ctl:Panel.ZIndex="99">
<Label.Foreground>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FFF70B0B"
Offset="0" />
<GradientStop Color="#FF480C0C"
Offset="1" />
</LinearGradientBrush>
</Label.Foreground>
<Label.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FF000000"
Offset="0" />
<GradientStop Color="#FFFFFFFF"
Offset="1" />
</LinearGradientBrush>
</Label.Background>
</ctl:Label>
</ctl:Grid>
</ctl:Border>
</ctl:Grid>
</Grid><!-- Triggers -->
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Opacity"
TargetName="DockListBoxLayoutRoot"
Value="0.5" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Foreground"
TargetName="DockListBoxLabel"
Value="DarkRed" />
<Setter Property="Fill"
TargetName="DockListBoxOuterEllipse"
Value="{StaticResource MouseOverFillBrush}" />
<Setter Property="Effect"
TargetName="DockListBoxOuterEllipse">
<Setter.Value>
<DropShadowEffect Direction="240"
Color="#AF999944" />
</Setter.Value>
</Setter>
</Trigger><!-- Data Triggers -->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelectedIndex}"
Value="0">
<Setter Property="Tag"
Value="-90" />
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="SB270">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RotorBorderRotateTransform"
Storyboard.TargetProperty="Angle"
Duration="0:0:1"
FillBehavior="HoldEnd">
<SplineDoubleKeyFrame Value="270"
KeySpline="0,0.6,1,0.4"
KeyTime="0:0:1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="SB270" />
</DataTrigger.ExitActions>
</DataTrigger><DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelectedIndex}"
Value="1">
<Setter Property="Tag"
Value="0" />
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="SB0">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RotorBorderRotateTransform"
Storyboard.TargetProperty="Angle"
Duration="0:0:1"
FillBehavior="HoldEnd">
<SplineDoubleKeyFrame Value="0"
KeySpline="0,0.6,1,0.4"
KeyTime="0:0:1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="SB0" />
</DataTrigger.ExitActions>
</DataTrigger><DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelectedIndex}"
Value="2">
<Setter Property="Tag"
Value="90" />
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="SB90">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RotorBorderRotateTransform"
Storyboard.TargetProperty="Angle"
Duration="0:0:1"
FillBehavior="HoldEnd">
<SplineDoubleKeyFrame Value="90"
KeySpline="0,0.6,1,0.4"
KeyTime="0:0:1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="SB90" />
</DataTrigger.ExitActions>
</DataTrigger><DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SelectedIndex}"
Value="3">
<Setter Property="Tag"
Value="180" />
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="SB180">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="RotorBorderRotateTransform"
Storyboard.TargetProperty="Angle"
Duration="0:0:1"
FillBehavior="HoldEnd">
<SplineDoubleKeyFrame Value="180"
KeySpline="0,0.6,1,0.4"
KeyTime="0:0:1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="SB180" />
</DataTrigger.ExitActions>
</DataTrigger></ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>- Changed TypeLinda LiuMSFT, ModeratorWednesday, November 04, 2009 10:45 AMNo follow up from OP
All Replies
Hi Korondy,
MSDN Subscriber Support in Forum
It's difficult to reproduce the problem only from the XAML you showed. Could you please reproduce the problem in a simple project and send it to me? My email address is v-lliu@microsoft.com.
Sincerely,
Linda Liu
If you have any feedback on our support, please contact msdnmg@microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.- Hi Korondy,
How about the problem now? I haven't received your sample project until now.
If you need our help, please feel free to let me know.
Sincerely,
Linda Liu
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us. - We are changing the issue type to “General Discussion” because you have not followed up with the necessary information. If you have more time to look at the issue and provide more information, please feel free to change the issue type back to “Question” by opening the Options list at the top of the post window, and changing the type. If the issue is resolved, we will appreciate it if you can share the solution so that the answer can be found and used by other community members having similar questions.


