Binding to PathFigure.StartPoint. AKA whats wrong with this XAML?
I have an ItemsControl that holds a collection of objects. It makes use of an ItemContainerStyle that looks like the following
<Style TargetType="{x:Type ContentPresenter}">
<Style.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
<DoubleAnimationUsingPath
Storyboard.TargetProperty="(Canvas.Top)"
Duration="0:0:5"
Source="Y"
RepeatBehavior="Forever">
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="10,10"> ........The above works fine...
However if i try to bind StartPoint to a property on my custom data source...eg
<PathFigure StartPoint="{Binding Path=MyPoint}">
I get an error stating "Item has already been added. Key in dictionary....etc etc etc"
By the way, the ItemsControl is correctly populated and displays data via a DataTemplate not shown here for simplicity.
Any ideas?
Answers
- Nick, no I never got it working. I opted for the easy way out and just wrote the code in C# instead. I'll revisit the problem now that I have a slightly better understanding of how styles and templates work together.
All Replies
- Did you try to rebuild the entire solution?
So you are trying to data bind the start point of a path used in defining the values of an animation?
My guess is that being a freezable it is being frozen prior to the animation being started, and the data binding is trying to modify the property value after it is frozen. Since you cut off the error message it is hard to say.
Hi Michael, sorry about that, I thought the error message snippet was generic enough to deduce. But here is the full error message...
{"Error at element 'ResourceDictionary' in markup file 'Window1.xaml' : Item has already been added. Key in dictionary: 'myDataSource' Key being added: 'myDataSource'."}
Seems it's not very helpful though.
And yes you're exactly right, I'm trying to data bind the start point of a path used in defining the values of an animation. I hadn't come across the concept of Freezable objects until now. Hmm.
Ok, based on Michaels post, I investigated Freezable objects and came away with the information that WPF doesn't support Freezable objects inside Templates or Styles unless they are first frozen. I think the runtime will freeze any freezable objects inside a Style or Template.
Anyway, this changes myproblem somewhat.
I was thinking, I can declare my EventTrigger directly under ItemsControl ie....
<ItemsControl ItemsSource="{Binding Source={StaticResource myDataSource}}" ItemTemplate="{StaticResource myDataTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="100" Height="100" Background="Black" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel><ItemsControl.Triggers>
<EventTrigger RoutedEvent="XXXX">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ParallelTimeline>
<DoubleAnimationUsingPath
Storyboard.TargetProperty="(Canvas.Top)"
Duration="0:0:5"
Source="Y"
RepeatBehavior="Forever"
>
<DoubleAnimationUsingPath.PathGeometry>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure StartPoint="{Binding Path=MyProperty}">What I'm struggling with now is what Event should I setting the EventTrigger's RoutedEvent property to (shown as XXXX in the code sample). My ItemsControl uses a DataTemplate that displays TextBlocks. I've tried <EventTrigger RoutedEvent="TextBlock.Loaded"> and even <EventTrigger RoutedEvent="ItemsControl.Loaded"> but neither one is able to kick off the animation.
I feel like I'm soooo close. Any ideas?- Did you ever get this working? You are animating the Canvas.Top property, are you sure there's someone listening to the property? (Your two samples are animating two different elements, the first animates the item and the second animates the ItemsControl...)
- Nick, no I never got it working. I opted for the easy way out and just wrote the code in C# instead. I'll revisit the problem now that I have a slightly better understanding of how styles and templates work together.

