ScaleTransform for Image - wpf

I am trying to increase the size of the image by 20. So I am using ScaleTransform as shown below.. but the following code doesn't do any scale Tranform.. Any help would be appreciated...
<Grid>
<Canvas>
<Canvas Height="50" Width="50" Canvas.Top="10" Canvas.Left="100"
Visibility="Visible">
<Image Name="Img" Source="Help.PNG" Canvas.Left="0" Canvas.Top="0">
</Image>
</Canvas>
<Button Canvas.Left="100" Canvas.Top="100" Height="42.5" Name="button3"
Width="100" Visibility="Visible">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard Name="MoveBox">
<DoubleAnimation Storyboard.TargetName="Img"
Storyboard.TargetProperty="(Image.RenderTransform).(ScaleTransform.ScaleX)"
From="1" To="20" BeginTime="0:0:3.75" Duration="0:0:1.25" />
<DoubleAnimation Storyboard.TargetName="Img"
Storyboard.TargetProperty="(Image.RenderTransform).(ScaleTransform.ScaleY)"
From="1" To="20" BeginTime="0:0:3.75" Duration="0:0:1.25" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
</Canvas>
</Grid>

Have you tried setting a <RenderTransform> on the image? Something like this:
<Image Name="Img" Source="Help.PNG" Canvas.Left="0" Canvas.Top="0">
<Image.RenderTransform>
<ScaleTransform x:Name="scale" ScaleX="1" ScaleY="1"
CenterX="0.5" CenterY="0.5" />
</Image.RenderTransform>
</Image>
This initialises the RenderTransform so that you can refer to it from elsewhere.
I've had to do this with Silverlight.

Related

Flicker on bars

I have the XAML code below but it's not smooth and creates flicker once in a while. How can i improve this in XAML? I have tried multiple solutions but it always seem to create flicker multiple times within a minute. Is this because of the frame rate of my monitor and the source code or? Please help. If you have examples on getting this smooth i would appreciate it.
<Window x:Class="BarsTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:BarsTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Orientation="Horizontal" Background="Black">
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform0" X="-160" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform1" X="160" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform2" X="480" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform3" X="800" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform4" X="1120" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform5" X="1440" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Height="1080" Width="160" Fill="White">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform6" X="1760" Y="0" />
</Rectangle.RenderTransform>
</Rectangle>
<StackPanel.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Name="myBeginStoryboard">
<Storyboard DesiredFrameRate="60">
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform0" Storyboard.TargetProperty="X" From="-160" To="160" Duration="0:0:0.5"/>
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform1" Storyboard.TargetProperty="X" From="0" To="320" Duration="0:0:0.5"/>
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform2" Storyboard.TargetProperty="X" From="160" To="480" Duration="0:0:0.5" />
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform3" Storyboard.TargetProperty="X" From="320" To="640" Duration="0:0:0.5" />
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform4" Storyboard.TargetProperty="X" From="480" To="800" Duration="0:0:0.5" />
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform5" Storyboard.TargetProperty="X" From="640" To="960" Duration="0:0:0.5" />
<DoubleAnimation RepeatBehavior="Forever" Storyboard.TargetName="AnimatedTranslateTransform6" Storyboard.TargetProperty="X" From="800" To="1120" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
</StackPanel>
</Grid>
</Window>
Br
ARUS

How can I Animate Image (Change the Position of any Image on Grid) By Clicking a Shape?

I wanna Move or Change position of an Image by clicking Another component.
I know How to change an Image location by clicking it. This code shows.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="Image">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(RenderTransform).(TranslateTransform.Y)"
Duration="0:0:2"
To="-279">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Canvas Margin="10">
<Rectangle Fill="Blue"
Height="150"
Width="150" Canvas.Left="269" Canvas.Top="139">
</Rectangle>
<Image x:Name="image" Source="Images/circle_yellow.png" Height="100" Canvas.Left="50" Canvas.Top="162" Width="100">
<Image.RenderTransform>
<TranslateTransform/>
</Image.RenderTransform>
</Image>
</Canvas>
</Grid>
But I wanna be Able to click the rectangle, not the Image. and Make the Image Move
Try this:
<Canvas Margin="10">
<Rectangle Fill="Blue"
Height="150"
Width="150" Canvas.Left="269" Canvas.Top="139">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="MouseLeftButtonUp">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="image"
Storyboard.TargetProperty="(RenderTransform).(TranslateTransform.Y)"
Duration="0:0:2"
To="-279">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<Image x:Name="image" Source="Images/circle_yellow.png" Height="100" Canvas.Left="50" Canvas.Top="162" Width="100">
<Image.RenderTransform>
<TranslateTransform/>
</Image.RenderTransform>
</Image>
</Canvas>

'ScaleTransform' name cannot be found in the name scope of 'System.Windows.Controls.ListView'

Whay I give that error "'ScaleTransform' name cannot be found in the name scope of 'System.Windows.Controls.ListView'." when ScaleTransform in another trigger, but whe I set it in Image.Triggers it work fine?
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Image x:Name="Img" Source="{Binding Source}" Height="128" Width="128" Focusable="True">
<Image.RenderTransform>
<ScaleTransform x:Name="MyAnimatedScaleTransform" CenterX="25" CenterY="25" ScaleX="1" ScaleY="1" />
</Image.RenderTransform>
</Image>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Triggers>
<EventTrigger RoutedEvent="ListView.SelectionChanged">
<BeginStoryboard Name="myBeginStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyAnimatedScaleTransform" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:0.25" AutoReverse="True" />
<DoubleAnimation Storyboard.TargetName="MyAnimatedScaleTransform" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ListView.Triggers>
</ListView>
and I try that but also not working:
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Image x:Name="Img" Source="{Binding Source}" Height="128" Width="128" Focusable="True">
<Image.RenderTransform>
<ScaleTransform x:Name="MyAnimatedScaleTransform" CenterX="25" CenterY="25" ScaleX="1" ScaleY="1" />
</Image.RenderTransform>
</Image>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Triggers>
<EventTrigger RoutedEvent="ListView.SelectionChanged">
<BeginStoryboard Name="myBeginStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.Target="{Binding MyAnimatedScaleTransform}" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:0.25" AutoReverse="True" />
<DoubleAnimation Storyboard.Target="{Binding MyAnimatedScaleTransform}" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ListView.Triggers>
</ListView>
I find that controllers in DataTemplate cannot be accessed, so i change my cod Xaml to:
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Image x:Name="Img" Source="{Binding Source}" Height="128" Width="128" Focusable="True">
<Image.RenderTransform>
<ScaleTransform x:Name="MyAnimatedScaleTransform" CenterX="25" CenterY="25" ScaleX="1" ScaleY="1" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseDown">
<BeginStoryboard Name="myBeginStoryboard">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MyAnimatedScaleTransform" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:0.25" AutoReverse="True" />
<DoubleAnimation Storyboard.TargetName="MyAnimatedScaleTransform" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:0.25" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
Now I have been returned to my main problem, when I click second time on image before first animation be ended (Reverse), the image don't revert to original size.

RenderTransform in WPF causing unexpected layout changes

I am trying to animate a number of shapes within a visualbrush but when I perform a rotation the shapes 'pulse'. I am assuming that as the shapes rotate the bounding boxes are forcing a layout pass. However since I am using a RenderTransform I wasn't expecting this to trigger layout changes.
This code illustrates the problem:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="200">
<StackPanel>
<Border BorderBrush="Red" BorderThickness="1"
Height="100" Width="100">
<Border.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="inner_Ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
<LinearDoubleKeyFrame KeyTime="0:0:3" Value="-360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
<LinearDoubleKeyFrame KeyTime="0:0:3" Value="360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<Border.Background>
<VisualBrush Stretch="Uniform">
<VisualBrush.Visual>
<Canvas Width="20" Height="20">
<Ellipse x:Name="outer_Ellipse"
Stroke="Blue" StrokeThickness="1"
Width="20" Height="20"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<RotateTransform/>
</Ellipse.RenderTransform>
</Ellipse>
<Ellipse x:Name="inner_Ellipse"
Stroke="Red" StrokeThickness="1"
Width="18" Height="18"
Margin="1,1,0,0"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<RotateTransform/>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</StackPanel>
This is a simple sample of a much more complicated application where I am using the Visual Brushes to decorate 2d planes being manipulated in 3d. It all works well until I try and animate the brushes. I have tried several different approaches but always seem to run into this layout issue.
Any suggestions appreciated.
Thanks
Rob
I was able to track down the cause of your problem. It has to do with the Stretch="Uniform" Property setting on your VisualBrush. It appears the framework is computing a bounding rectangle on your VisuaBrush.Visual, and then stretching it to fit Border.Background. The following code should illustrate the behavior. I took out your inner_Ellipse and added an outer_Rectangle that should simulate the bounding rectangle being stretched:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="200">
<StackPanel>
<Border BorderBrush="Red" BorderThickness="1"
Height="100" Width="100">
<Border.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Rectangle"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
<LinearDoubleKeyFrame KeyTime="0:0:6" Value="360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
<LinearDoubleKeyFrame KeyTime="0:0:6" Value="360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<Border.Background>
<VisualBrush Stretch="Uniform">
<VisualBrush.Visual>
<Canvas Width="20" Height="20">
<Ellipse x:Name="outer_Ellipse"
Stroke="Blue" StrokeThickness="1"
Width="20" Height="20"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<RotateTransform/>
</Ellipse.RenderTransform>
</Ellipse>
<Rectangle x:Name="outer_Rectangle"
Stroke="Blue" StrokeThickness="1"
Width="20" Height="20"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<RotateTransform/>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</StackPanel>
</Window>
As to solving the problem, I am not sure. One way would be to use Stretch="None" on your VisualBrush, but that doesn't seem ideal because it then falls on you to deal with the size of your VisualBrush.Visual contents.
Well after a good deal of trial and error I have a working solution. The contents of the VisualBrush correctly scale and don't cause the bounding box problem:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
SizeToContent="WidthAndHeight" >
<StackPanel>
<Border BorderBrush="Black" BorderThickness="1"
Height="400" Width="400">
<Border.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="inner_Ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
<LinearDoubleKeyFrame KeyTime="0:0:3" Value="-360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever" >
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="outer_Ellipse"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)">
<LinearDoubleKeyFrame KeyTime="0:0:3" Value="360"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<Border.Background>
<VisualBrush Stretch="UniformToFill">
<VisualBrush.Visual>
<Border BorderBrush="Transparent" BorderThickness="1"
Width="200" Height="200">
<StackPanel Width="200" Height="200">
<Canvas>
<Rectangle x:Name="outer_Ellipse"
Stroke="Blue" StrokeThickness="1"
Width="20" Height="200"
Canvas.Left="40"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<RotateTransform/>
</Rectangle.RenderTransform>
</Rectangle>
<Ellipse x:Name="inner_Ellipse"
Stroke="Red" StrokeThickness="1"
StrokeDashArray="2"
Canvas.Top="30"
Canvas.Left="20"
Width="200" Height="200"
RenderTransformOrigin="0.5,0.5">
<Ellipse.RenderTransform>
<RotateTransform/>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</StackPanel>
</Border>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>
</Border>
</StackPanel>
</Window>
The 'secret' appears to be wrapping the canvas containing the brush contents in a StackPanel and wrapping this in a Border. (a Grid, DockPanel and WrapPanel will also work in place of the StackPanel).
<Border BorderBrush="Transparent" BorderThickness="1"
Width="200" Height="200">
<StackPanel Width="200" Height="200">
The Border must have a BorderBrush set and a BorderThickness. Also they must both have an explicit width and height. Here I have set values appropriate to the content so it scales correctly.
Without all 3 of these components the bounding box issue re occurs. Clearly something about the layout policies of the containers makes a difference but I have no idea what or why.
Not at all a satisfying solution and I would appreciate it if anyone can shine a light on what's going on here.
At least it works, both in the above demo and my main application, so far anyway!
Rob

help me please with a Popup

I have an Image and a Popup. When clicked on the Image popup should open.
I started like that and now I stuck.
<Image x:Name="LockImage" Source="/Lock.png">
<Image.Triggers>
<EventTrigger RoutedEvent="MouseDown">
// ?????? WHAT's here?
</EventTrigger>
</Image.Triggers>
</Image>
<Popup x:Name="LockPopup" PlacementTarget="{Binding ElementName=LockImage}">
<TextBlock Text="This is a popup" />
</Popup>
UPD... Ooops, actually I forgot... I'd like the popup to be shown not immediately but rather after a second or two. If it was just a click, It would be something else... (default action)
Here is the solution of what you want to do. Delay time can be set at Storyboard definitions. Insert this code into new wpf app project Window.xaml file.
<Window.Resources>
<Storyboard x:Key="ShowPopup">
<BooleanAnimationUsingKeyFrames Storyboard.TargetName="LockPopup" Storyboard.TargetProperty="(Popup.IsOpen)">
<DiscreteBooleanKeyFrame KeyTime="00:00:00.5" Value="True" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HidePopup" Storyboard.TargetName="LockPopup" Storyboard.TargetProperty="(Popup.IsOpen)">
<BooleanAnimationUsingKeyFrames>
<DiscreteBooleanKeyFrame KeyTime="00:00:00.5" Value="False" />
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid x:Name="grid" ShowGridLines="True">
<Image x:Name="LockImage" Stretch="None" >
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="10" RadiusY="10"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.MouseLeftButtonDown">
<BeginStoryboard Storyboard="{StaticResource ShowPopup}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Image.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource HidePopup}"/>
</EventTrigger>
</Image.Triggers>
</Image>
<Popup x:Name="LockPopup" PlacementTarget="{Binding ElementName=LockImage}" DataContext="{Binding}" Placement="Bottom">
<TextBlock Text="This is a popup" Background="White" Foreground="Black" />
</Popup>
</Grid>

Resources