If anyone has tried the XamlWriter (which I am sure no one has, yet!) it would be clear that it doesn't work for Storyboards and TransformGroups. That is because they are a slightly special case. Why? I'll leave that for some future post. Anyways it's fixed now.
Please check out my previous post for download and usage information.
I also thought I'd take this opportunity to point out some issue that I encountered. If you had read my previous posts on this subject you would know that I used reflection to implement the XamlWriter.
The way to retrieve the properties of an object using reflection is like this -
PropertyInfo[] props = target.GetType().GetProperties();
I now needed to to check if the property is readonly. The reason for this is that a readonly property cannot be used in Xaml. So I went ahead and used the CanWrite property to check if the property could be written to, like this -
if (!prop.CanWrite)
But, guess what? It doesn't work in all cases. For example, the IsFocussed property of a Button control returns true for CanWrite. I put the IsFocussed property in the Xaml and it threw an error indicating clearly that this was a read only property.
So there had to be a different way. After all the Xaml parser knows more about readonly properties than the CanWrite property. That is when I discovered the GetSetMethod method on ProperyInfo. This worked wonderfully -
if (prop.GetSetMethod == null)
Whether this is a bug or some explainable feature, I don't know. Maybe I will post this on the Silverlight.net forums and see if there is an explanation. In the meantime, there is a workaround for me to continue making progress!
The Storyboard and TransformGroup example
Assuming an Xaml like this <UserControl x:Class="test2.MainPage" x:Name="MyControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="850" Height="447"> <Canvas> <Canvas.Triggers> <EventTrigger RoutedEvent="Canvas.Loaded"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation To="300" Duration="0:0:1" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Left)" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Canvas.Triggers> <Canvas.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1.05" ScaleY="1"/> <SkewTransform AngleX="0" AngleY="0"/> <RotateTransform Angle="0"/> <TranslateTransform X="1" Y="0"/> </TransformGroup> </Canvas.RenderTransform> <Ellipse x:Name="ellipse" Height="20" Width="20" Canvas.Left="30" Canvas.Top="30" Fill="black"/> <Button x:Name="zz" Width="100" Height="100" Click="Button_Click"/> </Canvas> </UserControl> WriteXaml(MyControl, XamlWriterSettings.LogicalTree) will generate this Xaml <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="MyControl"> <Canvas> <Ellipse Width="20" Height="20" x:Name="ellipse" Canvas.Left="300" Canvas.Top="30" Fill="#FF000000" /> <Button Width="100" Height="100" x:Name="zz" /> <Canvas.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation To="300" Duration="00:00:01" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Canvas.Left)" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Canvas.Triggers> <Canvas.RenderTransform> <TransformGroup> <ScaleTransform ScaleX="1.04999995231628" /> <SkewTransform /> <RotateTransform /> <TranslateTransform X="1" /> </TransformGroup> </Canvas.RenderTransform> </Canvas> </UserControl>
No comments:
Post a Comment