Strange Container problem
-
I have a container (Grid or any other Container) which holds another Canvas which has a background image. My xaml file looks something like this. <Window x:Class="Billboard.WinMain" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WinMain" Height="507" Width="676"> <Window.Resources> <Storyboard x:Key="EmbaddedCanvas"> <DoubleAnimation Storyboard.TargetName="myCanvas" Storyboard.TargetProperty="(Canvas.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:5" From="1" To="0"/> </Storyboard> <ImageBrush x:Key="IBKey" ImageSource="Images/Crystal.jpg" /> </Window.Resources> <Grid x:Name=" ParentGrid " Height="475" Width="660"> <Canvas x:Name="myCanvas" Height="475" Width="660" Background="{StaticResource IBKey}" > <Canvas.RenderTransform> <ScaleTransform CenterX="330" CenterY="0" ScaleX="1" ScaleY="1" /> </Canvas.RenderTransform> </Canvas> </Grid> </Window> In my code I just call Storyboard sbAnimate = (Storyboard)Resources["EmbaddedCanvas"]; sbAnimate.Begin(); It works fine. No problem. This was an experiment. But in real application the image is dynamic and I had to create Canvas on the fly. So my xmal code looks something like this and I will add ParentGrid <Grid x:Name="ParentGrid" Height="475" Width="660"> </Grid> Now my code behind likes like this and I can see the image but no animation. Image finalImage = new Image(); BitmapImage logo = new BitmapImage(); logo.BeginInit(); logo.UriSource = new Uri("pack://application:,,,/Billboard;component/Images/Crystal.jpg"); logo.EndInit(); finalImage.Source = logo; Canvas myCanvas = new Canvas(); myCanvas.Width = 660; myCanvas.Height = 475; myCanvas.Background = new ImageBrush(finalImage.Source); this.ParentGrid.Children.Add(myCanvas); myCanvas.Children.Add(finalImage); Storyboard sb = new Storyboard(); ScaleTransform scaleTransform = new ScaleTransform(1.0, 1.0, 330, 0); myCanvas.RenderTransformOrigin = new Point(0, 0); myCanvas.RenderTransform = scaleTransform; DoubleAnimation growAnimation = new Doub
-
I have a container (Grid or any other Container) which holds another Canvas which has a background image. My xaml file looks something like this. <Window x:Class="Billboard.WinMain" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="WinMain" Height="507" Width="676"> <Window.Resources> <Storyboard x:Key="EmbaddedCanvas"> <DoubleAnimation Storyboard.TargetName="myCanvas" Storyboard.TargetProperty="(Canvas.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:5" From="1" To="0"/> </Storyboard> <ImageBrush x:Key="IBKey" ImageSource="Images/Crystal.jpg" /> </Window.Resources> <Grid x:Name=" ParentGrid " Height="475" Width="660"> <Canvas x:Name="myCanvas" Height="475" Width="660" Background="{StaticResource IBKey}" > <Canvas.RenderTransform> <ScaleTransform CenterX="330" CenterY="0" ScaleX="1" ScaleY="1" /> </Canvas.RenderTransform> </Canvas> </Grid> </Window> In my code I just call Storyboard sbAnimate = (Storyboard)Resources["EmbaddedCanvas"]; sbAnimate.Begin(); It works fine. No problem. This was an experiment. But in real application the image is dynamic and I had to create Canvas on the fly. So my xmal code looks something like this and I will add ParentGrid <Grid x:Name="ParentGrid" Height="475" Width="660"> </Grid> Now my code behind likes like this and I can see the image but no animation. Image finalImage = new Image(); BitmapImage logo = new BitmapImage(); logo.BeginInit(); logo.UriSource = new Uri("pack://application:,,,/Billboard;component/Images/Crystal.jpg"); logo.EndInit(); finalImage.Source = logo; Canvas myCanvas = new Canvas(); myCanvas.Width = 660; myCanvas.Height = 475; myCanvas.Background = new ImageBrush(finalImage.Source); this.ParentGrid.Children.Add(myCanvas); myCanvas.Children.Add(finalImage); Storyboard sb = new Storyboard(); ScaleTransform scaleTransform = new ScaleTransform(1.0, 1.0, 330, 0); myCanvas.RenderTransformOrigin = new Point(0, 0); myCanvas.RenderTransform = scaleTransform; DoubleAnimation growAnimation = new Doub
Hi, maybe you should consider binding the Canvas.Background instead of using a static resource. Then you can leave everything in the XAML as it is (you can even eliminate the Grid as it is not needed). Load the BGBrush into a bound property and then do as you do right now; if necessary, you can bind the sizes of the Canvas/Window and set the properties according to the loaded image. Cheers Jürgen
-
Hi, maybe you should consider binding the Canvas.Background instead of using a static resource. Then you can leave everything in the XAML as it is (you can even eliminate the Grid as it is not needed). Load the BGBrush into a bound property and then do as you do right now; if necessary, you can bind the sizes of the Canvas/Window and set the properties according to the loaded image. Cheers Jürgen
Thanks for reply. Well your suggestions are appreciated and binding with background make sense, but my question was diffrent why it does not animate? After playing 4 days I came to a solution, which I believe is not elegant, but it works. Basically we have to look closely PropertyPath which was set to ScaleTransform.ScaleXProperty and it should be "(Canvas.RenderTransform).(ScaleTransform.ScaleX)" but equal in code behind? I was unable to find any help. To bring complicated PropertyPath I have a create StoryBoard in xaml with a factious TargetName. <Storyboard x:Key="EmbaddedCanvas"> <DoubleAnimation Storyboard.TargetName="JohnDow" Storyboard.TargetProperty="(Canvas.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:5" From="1" To="0"/> </Storyboard> and Register my Canvas with that name. At the end call that story board. RegisterName("JohnDow", myCanvas); Storyboard sbAnimate = (Storyboard)Resources["EmbaddedCanvas"]; growAnimation.SetValue(Storyboard.TargetNameProperty, "JohnDow"); sbAnimate.Begin(); It works. At the end everything we have done to bring TargetPropert from xaml, but what is equal in code behind of Storyboard.TargetProperty="(Canvas.RenderTransform).(ScaleTransform.ScaleX)"? You might know, but I am unable to find the answer. My solution works but it is not elegant. Best regards Agha Khan
-
Thanks for reply. Well your suggestions are appreciated and binding with background make sense, but my question was diffrent why it does not animate? After playing 4 days I came to a solution, which I believe is not elegant, but it works. Basically we have to look closely PropertyPath which was set to ScaleTransform.ScaleXProperty and it should be "(Canvas.RenderTransform).(ScaleTransform.ScaleX)" but equal in code behind? I was unable to find any help. To bring complicated PropertyPath I have a create StoryBoard in xaml with a factious TargetName. <Storyboard x:Key="EmbaddedCanvas"> <DoubleAnimation Storyboard.TargetName="JohnDow" Storyboard.TargetProperty="(Canvas.RenderTransform).(ScaleTransform.ScaleX)" Duration="0:0:5" From="1" To="0"/> </Storyboard> and Register my Canvas with that name. At the end call that story board. RegisterName("JohnDow", myCanvas); Storyboard sbAnimate = (Storyboard)Resources["EmbaddedCanvas"]; growAnimation.SetValue(Storyboard.TargetNameProperty, "JohnDow"); sbAnimate.Begin(); It works. At the end everything we have done to bring TargetPropert from xaml, but what is equal in code behind of Storyboard.TargetProperty="(Canvas.RenderTransform).(ScaleTransform.ScaleX)"? You might know, but I am unable to find the answer. My solution works but it is not elegant. Best regards Agha Khan
Hi, sorry. I didn't want to ignore your question, but the proposed solution seemed so simple and yet right to me, that I oversaw, there might be further points of interest. So, let's go through it a bit more detailed: Your (original) code contained two flaws, that prevented it from working. 1. As you've found yourself: The PropertyPath must be built with "(Canvas.RenderTransform).(ScaleTransform.ScaleX)" - not ScaleXProperty. That is right for the code behind too. 2. (harder to catch) When you construct the Canvas (and implicitly the RenderTransform) it is created as a "TransformGroup" (see the 'usual' XAML - this is, what will be constructed by "Canvas myCanvas = new Canvas();"):
...
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform CenterX="330" CenterY="0" ScaleX="1" ScaleY="1" />
<SkewTransform
...
</TransformGroup>
</Canvas.RenderTransform>
...As it is immutable, you must re-init the RenderTransform with
myCanvas.RenderTransform = new ScaleTransform(1, 1, 330, 0);
Otherwise the Default(=Matrix)Transformation can not be cast into a ScaleTransformation and just nothing happens. Finally you made one good point: using name registering - espescially with such a funny name - instead of data binding does not seem elegant to me either. But it's your solution so be it your choice. My last proposal: make it "MyCanvas" instead of "JohnDow"... Regards Jürgen
-
Hi, maybe you should consider binding the Canvas.Background instead of using a static resource. Then you can leave everything in the XAML as it is (you can even eliminate the Grid as it is not needed). Load the BGBrush into a bound property and then do as you do right now; if necessary, you can bind the sizes of the Canvas/Window and set the properties according to the loaded image. Cheers Jürgen
Thank you for your email again. I was not aware that "(Canvas.RenderTransform).(ScaleTransform.ScaleX)" is also right for the code behind. Thank you. And it worked. :laugh: I did exectely what you are asking for. myCanvas.RenderTransform = new ScaleTransform(1, 1, 330, 0); It worked. I see your name with (U with 2 dots) which implies you are from North Europe. In USA we use JohnDow for Unknown. :laugh: Thanks Best regards Agha Khan
-
Thank you for your email again. I was not aware that "(Canvas.RenderTransform).(ScaleTransform.ScaleX)" is also right for the code behind. Thank you. And it worked. :laugh: I did exectely what you are asking for. myCanvas.RenderTransform = new ScaleTransform(1, 1, 330, 0); It worked. I see your name with (U with 2 dots) which implies you are from North Europe. In USA we use JohnDow for Unknown. :laugh: Thanks Best regards Agha Khan
Yep, it's Germany; and the dots are a neverending source of hassle. You wont believe how many websites, software ... and hence programmers think, if their tests covered a..z they're ready for unicode. I wonder, what asian people could say about that... ;) Ooops, I thought it was John (& Jane) Doe, but I got what you meant ... and that's why I supposed you give the Canvas a more 'speaking' name. BTW: Why do you use a Canvas with an ImageBrush background? A sole Image would do the same. Regards Jürgen