SplineDoubleKeyFrame set from DynamicResource
- I want to use a dynamic resource to give the rotate transform angle to a SplineDoubleKeyFrame. I've used dynamic resources to do this on a doubleAnimation.ToI can set it in code behind if I reference the key by its index, if I do this instead:DoubleAnimationUsingKeyFramesdaukf=(DoubleAnimationUsingKeyFrames)TryFindResource("thisOne");((SplineDoubleKeyFrame)daukf.KeyFrames[0]).Value = 19;But this just makes me more curious as to why I can't do that in xaml.Can anyone tell me why this doesn't work?thanks
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="UntitledProject1.Window1" xmlns:sys="clr-namespace:System;assembly=mscorlib" x:Name="Window" Title="Window1" Width="640" Height="480"> <Window.Resources> <sys:Double x:Key="sdKey">18.545</sys:Double> <DoubleAnimationUsingKeyFrames x:Key="thisOne" BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> <SplineDoubleKeyFrame KeyTime="00:00:0.5" Value="{DynamicResource sdKey}"/> </DoubleAnimationUsingKeyFrames> </Window.Resources> <Grid x:Name="LayoutRoot"> <Rectangle Fill="#FFB70000" Stroke="#FF000000" HorizontalAlignment="Right" Margin="0,160,232,206" Width="80" RenderTransformOrigin="-3,0" x:Name="rectangle"> <Rectangle.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1" ScaleY="1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="0"/> <TranslateTransform X="0" Y="0"/> </TransformGroup> </Rectangle.RenderTransform> </Rectangle> <Button Height="30" HorizontalAlignment="Right" Margin="0,44,42,0" Name="button1" VerticalAlignment="Top" Width="117" Click="button1_Click">Button</Button> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Media.Animation; namespace UntitledProject1 { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { Storyboard sb = new Storyboard(); public Window1() { this.InitializeComponent(); // Insert code required on object creation below this point. } private void button1_Click(object sender, RoutedEventArgs e) { sb.Children.Add((DoubleAnimationUsingKeyFrames)TryFindResource("thisOne")); sb.Begin(this, true); } } }
- Edited byzaurska Monday, October 26, 2009 10:49 PMadditional info
Answers
Hi Zaurska,
Using DynamicResource markup extensions in XAML equals to setting resource reference in code. For example:
XAML
<TextBlock Name="txtbox" Background="{DynamicResource myBrush}"/>
code behind
this.txtbox.SetResourceReference(TextBlock.BackgroundProperty, "myBrush");
Note that only FrameworkElement or FrameworkContentElement or FrameworkElementFactory class has the SetResourceReference method. That's to say, we can only associate property with a resource on FrameworkElement or FrameworkContentElement or FrameworkElementFactory. The SplineDoubleKeyFrame is not any of above types, so it couldn't be associated with a resource, i.e. using DynamicResource on the SplineDoubleKeyFrame has no effect.
Changing the "DynamicResource" to "StaticResource" in the XAML can solve the problem. For example:
<DoubleAnimationUsingKeyFrames x:Key="thisOne"
BeginTime="00:00:00"
Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:0.5" Value="{StaticResource sdKey}"/>
</DoubleAnimationUsingKeyFrames>
Hope this helps.
If you have any question, 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.- Marked As Answer byLinda LiuMSFT, ModeratorMonday, November 02, 2009 2:48 AM
Hi Zaurska,
You can bind the Value property of the SplineDoubleKeyFrame to a property of a business class. Change the value of the business class property at run time and the SplineDoubleKeyFrame.Value property will be changed. For example:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="UntitledProject1.Window1"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:UntitledProject1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
<Window.Resources>
<local:MyValueClass x:Key="myvalue" Value="18.545"/>
<DoubleAnimationUsingKeyFrames x:Key="thisOne"
BeginTime="00:00:00"
Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:0.5" Value="{Binding Source={StaticResouce myvalue}, Path=Value}"/>
</DoubleAnimationUsingKeyFrames>
</Window.Resources>
....
</Window>
code behind
public class MyValueClass:INotifyPropertyChanged
{
private double _value;
public double Value
{
get { return _value; }
set {
_value = value;
OnPropertyChanged("Value");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propname)
{
if(PropertyChanged !=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propname));
}
}
}
the code to change the property value:
private void button1_Click(object sender, RoutedEventArgs e)
{
(this.Resources["myvalue"] as MyValueClass).Value = 15;
}
Hope this helps.
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.- Marked As Answer byzaurska Wednesday, November 04, 2009 10:41 PM
All Replies
Hi Zaurska,
Using DynamicResource markup extensions in XAML equals to setting resource reference in code. For example:
XAML
<TextBlock Name="txtbox" Background="{DynamicResource myBrush}"/>
code behind
this.txtbox.SetResourceReference(TextBlock.BackgroundProperty, "myBrush");
Note that only FrameworkElement or FrameworkContentElement or FrameworkElementFactory class has the SetResourceReference method. That's to say, we can only associate property with a resource on FrameworkElement or FrameworkContentElement or FrameworkElementFactory. The SplineDoubleKeyFrame is not any of above types, so it couldn't be associated with a resource, i.e. using DynamicResource on the SplineDoubleKeyFrame has no effect.
Changing the "DynamicResource" to "StaticResource" in the XAML can solve the problem. For example:
<DoubleAnimationUsingKeyFrames x:Key="thisOne"
BeginTime="00:00:00"
Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:0.5" Value="{StaticResource sdKey}"/>
</DoubleAnimationUsingKeyFrames>
Hope this helps.
If you have any question, 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.- Marked As Answer byLinda LiuMSFT, ModeratorMonday, November 02, 2009 2:48 AM
- thank you,I need sdKey to increment at runtime, and the storyboard to respond to that change, if its a Static resource I cant change it, can I?In code behind I have done this instead:which does what I need.
Double currentAngle =Convert.ToDouble( ((TransformGroup)r.RenderTransform) .Children[2].GetValue(RotateTransform.AngleProperty) .ToString()); double d = currentAngle + 18; ((SplineDoubleKeyFrame)daukf.KeyFrames[0]).Value = d;I'd still like to do it in Xaml though Hi Zaurska,
You can bind the Value property of the SplineDoubleKeyFrame to a property of a business class. Change the value of the business class property at run time and the SplineDoubleKeyFrame.Value property will be changed. For example:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="UntitledProject1.Window1"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:UntitledProject1"
x:Name="Window"
Title="Window1"
Width="640" Height="480">
<Window.Resources>
<local:MyValueClass x:Key="myvalue" Value="18.545"/>
<DoubleAnimationUsingKeyFrames x:Key="thisOne"
BeginTime="00:00:00"
Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:0.5" Value="{Binding Source={StaticResouce myvalue}, Path=Value}"/>
</DoubleAnimationUsingKeyFrames>
</Window.Resources>
....
</Window>
code behind
public class MyValueClass:INotifyPropertyChanged
{
private double _value;
public double Value
{
get { return _value; }
set {
_value = value;
OnPropertyChanged("Value");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propname)
{
if(PropertyChanged !=null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propname));
}
}
}
the code to change the property value:
private void button1_Click(object sender, RoutedEventArgs e)
{
(this.Resources["myvalue"] as MyValueClass).Value = 15;
}
Hope this helps.
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.- Marked As Answer byzaurska Wednesday, November 04, 2009 10:41 PM
- even better,thanks so much!


