I have a Canvas element, which has a width of 1400 pixels and a height of 750 pixels. This Canvas contains 2 Path elements, which are symmetrical, along a vertical axis, and which are positioned side by side.
This Canvas is inside a ViewBox, because the user can resize the ContentControl owning the Canvas, and I want the Canvas to be scaled.
For now, I see both Paths in the ViewBox.
What I would like to do, is to only display the left half of the canvas in the ViewBox (with this half being correctly resized), and to be able to display the right half of the canvas with a translation of the canvas, using a storyboard and a property trigger.
I think I can cope with the animation part, but now I'm struggling with the display.
How would you write the XAML to have what I'd like?
Thanks in advance
Michael
I've just found how to do that:
I needed to put the Canvas in a grid with properties ClipToBounds set to true and Width to 700 (half of the width of the canvas), and put that grid in the viewbox.
Here is the complete XAML code, with the animation part too:
<UserControl x:Class="TestsCaliburn.Views.ChildView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
xmlns:Media="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
Background="Green">
<UserControl.Resources>
<Storyboard x:Key="MoveField">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="BackgroundCanvas">
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="{Binding XTransform}">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding XTransform}" Comparison="NotEqual" Value="1">
<Media:ControlStoryboardAction Storyboard="{StaticResource MoveField}"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
<Viewbox>
<Grid ClipToBounds="True" Width="750">
<Canvas Background="Yellow" Width="1400" Height="750" x:Name="BackgroundCanvas" RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Canvas.RenderTransform>
<Canvas.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding CanUse}" Value="false">
<Setter Property="FrameworkElement.Cursor" Value="No" />
</DataTrigger>
</Style.Triggers>
</Style>
</Canvas.Style>
<Path Stretch="Fill" Stroke="Blue" StrokeThickness="2" Fill="Transparent" x:Name="Background" Data="M700,0 L1400,0 L1400,750 L700,750 L700,0 L0,0 L0,750 L700,750 z"/>
<Path Stretch="Fill" Stroke="Red" StrokeThickness="2" Canvas.Top="45" x:Name="Inside3PointsLeft" Fill="Transparent" Data="M0,0 L150,0 A1,1,0,0,1,150,660 L0,660 z"/>
<Path Stretch="Fill" Stroke="Red" StrokeThickness="2" RenderTransformOrigin="0.5,0.5" Canvas.Top="45" Canvas.Right="0" x:Name="Inside3PointsRight" Fill="Transparent" Data="M0,0 L150,0 A1,1,0,0,1,150,660 L0,660 z">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
</Grid>
</Viewbox>
</UserControl>
I hope this will help someone :)
Related
What I am trying to achieve is to fit the Polyline inside a Viewbox. I tried the Stretch options, however it does not seem to work with negative values. Can someone guide how to fit the content inside the ViewBox?
Following is my sample code:
<Viewbox Stretch="Uniform">
<Grid>
<Polyline Margin="10" Fill="Tan" HorizontalAlignment="Center"
VerticalAlignment="Center" Points="0,0 14,0 14,-38"
StrokeThickness="1" Stroke="Black"
RenderTransformOrigin="0.5,0.5">
<Polyline.RenderTransform>
<TransformGroup>
<RotateTransform Angle="180"/>
<ScaleTransform>
<ScaleTransform.ScaleX>-1</ScaleTransform.ScaleX>
</ScaleTransform>
</TransformGroup>
</Polyline.RenderTransform>
</Polyline>
</Grid>
</Viewbox>
The bounds go beyond the Viewbox, hence unable to get it to "fit" the view.
You shouldn't set the RenderTransform of an element in a Viewbox.
Instead of a Polyline you may use a Path with a polyline geometry, where you can set the Transform property of the Geometry object in the Path's Data:
<Viewbox Stretch="Uniform">
<Path Margin="10" Fill="Tan" StrokeThickness="1" Stroke="Black"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Path.Data>
<PathGeometry Figures="M0,0 L14,0 14,-38">
<PathGeometry.Transform>
<TransformGroup>
<RotateTransform Angle="180"/>
<ScaleTransform>
<ScaleTransform.ScaleX>-1</ScaleTransform.ScaleX>
</ScaleTransform>
</TransformGroup>
</PathGeometry.Transform>
</PathGeometry>
</Path.Data>
</Path>
</Viewbox>
Edit: An alternative might be to set the LayoutTransform instead of RenderTransform. You would also have to set the Polyline's Stretch property:
<Viewbox>
<Polyline Margin="10" Fill="Tan" StrokeThickness="1" Stroke="Black"
Points="0,0 14,0 14,-38" Stretch="Uniform">
<Polyline.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="180"/>
<ScaleTransform>
<ScaleTransform.ScaleX>-1</ScaleTransform.ScaleX>
</ScaleTransform>
</TransformGroup>
</Polyline.LayoutTransform>
</Polyline>
</Viewbox>
Let's say that My ContentPresenter contains a Viewbox with Paths inside instead of some text, how do I change the Color of those Paths from the Content Presenter
Example
I have this ResourceDictionary :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Viewbox>
<Grid>
<Grid Name="backgroundGrid" Width="48" Height="48" Visibility="Collapsed" />
<Path Data="M19.833,0L32.5,0 32.5,19.833999 52.334,19.833999 52.334,32.500999 32.5,32.500999 32.5,52.333 19.833,52.333 19.833,32.500999 0,32.500999 0,19.833999 19.833,19.833999z"
Stretch="Uniform"
Fill="?????"
Width="26" Height="26" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
</Viewbox>
</ResourceDictionary>
and I have the ContentPresenter in a ControlTemplate of let's say a Button:
<ControlTemplate TargetType="{x:Type local:IconButton}">
<Border>
<Grid>
<ContentPresenter x:Name="ContentPresenterIcon" ContentSource="Icon"/>
</Grid>
</Border>
...
Assigning Icon to the ContentSource property just means that the ContentPresenter is having that Viewbox as a content.
What should I put in the Fill property of the Path Element, and which property should I change in the ContentPresenter to make its value propagate to the Fill property ?
Hope I was clear.
Update :
I desperately tried to set the ContentPresenter's TextElement.Foreground property and "Relativesource" bind the Path's Fill property to it, but that predictably didn't work.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Viewbox>
<Grid>
<Grid Name="backgroundGrid" Width="48" Height="48" Visibility="Collapsed" />
<Path Data="M19.833,0L32.5,0 32.5,19.833999 52.334,19.833999 52.334,32.500999 32.5,32.500999 32.5,52.333 19.833,52.333 19.833,32.500999 0,32.500999 0,19.833999 19.833,19.833999z"
Stretch="Uniform"
Fill="{Binding Path=TextElement.Foreground, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
Width="26" Height="26" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
</Viewbox>
<ControlTemplate TargetType="{x:Type local:IconButton}">
<Border>
<Grid>
<ContentPresenter x:Name="ContentPresenterIcon" TextElement.Foreground="Red" ContentSource="Icon"/>
</Grid>
</Border>
...
Your second attempt should have worked. The reason it didn't is because you are binding to an Attached Property.
Attached property binding requires special syntax. The output window in visual studio probably tells you that the path could not be found. This should work:
Fill="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
The only change is the parenthesis around the Path string. For more information, see WPF Attached Property Data Binding.
I am creating fun roulette game where I am trying to rotate eclipse with wheel image inside on its axis (but not 360 degree). Right now, some problem with its rotation, its not rotating as per my requirement. If you will run below code with images attached also. you will get my requirement.
Pls set your screen resolution i.e. Height="1024" Width="768" for understanding my exact requirement. I am also attaching images here. one is background image and another is wheel image.
I am stuck on this from last one week. Any help will be appreciable. Thanks in advance.
Title="MainWindow" Height="1024" Width="768"
WindowStyle="None"
WindowStartupLocation="CenterScreen" WindowState="Maximized">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames RepeatBehavior="Forever" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ball">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="360" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="Image/fun_roulette.jpg" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Ellipse Name="ball" Stroke="Black"
RenderTransformOrigin="0.5,0.5" Width="370" Height="200"
Grid.Row="0" Grid.Column="0" Opacity=".4"
Margin="0,30,0,0"
>
<Ellipse.RenderTransform>
<TransformGroup >
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="45" CenterX="0" CenterY="0" />
<TranslateTransform />
</TransformGroup>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<ImageBrush ImageSource="Image/Roullette_Wheel.jpg" />
</Ellipse.Fill>
<Ellipse.BitmapEffect>
<BevelBitmapEffect BevelWidth="0" />
</Ellipse.BitmapEffect>
<Ellipse.BitmapEffectInput>
<BitmapEffectInput />
</Ellipse.BitmapEffectInput>
</Ellipse>
</Grid>
Download Background Image from here
https://drive.google.com/file/d/0ByTbA6S0c1TaZEo2akgtQjVCbjQ/view?usp=sharing
Download Wheel Image from here
https://drive.google.com/file/d/0ByTbA6S0c1TaY1JzazhudDkzMjA/view?usp=sharing
As I understand you want the ellipse to rotate exactly at the position of the static disc in the background image. Also because of a little 3D effect (perspective effect), rotating the ellipse normally would not be able to produce the desired result. You can try using some 3D feature in WPF but it's some kind of overkill because we still have another choice.
Instead of rotating the whole ellipse, you can just rotate the ImageBrush. I've tried your code and tweaking it a little with some modifications and finally the effect seems to be what you want. Here is the code:
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames RepeatBehavior="Forever"
Storyboard.TargetProperty="Angle" Storyboard.TargetName="rot">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="0" />
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="360" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="Image/fun_roulette.jpg" />
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Ellipse Name="ball" Stroke="Black" RenderTransformOrigin="0.5,0.8"
Grid.Row="0" Grid.Column="0" Opacity=".4"
Margin="6,0,0,0">
<Ellipse.RenderTransform>
<ScaleTransform ScaleX=".195" ScaleY=".45"/>
</Ellipse.RenderTransform>
<Ellipse.Fill>
<ImageBrush ImageSource="Image/Roullette_Wheel.jpg">
<ImageBrush.RelativeTransform>
<TransformGroup >
<RotateTransform CenterX="0.5" CenterY="0.5" x:Name="rot"/>
<SkewTransform/>
<TranslateTransform />
</TransformGroup>
</ImageBrush.RelativeTransform>
</ImageBrush>
</Ellipse.Fill>
<Ellipse.BitmapEffect>
<BevelBitmapEffect BevelWidth="0" />
</Ellipse.BitmapEffect>
<Ellipse.BitmapEffectInput>
<BitmapEffectInput />
</Ellipse.BitmapEffectInput>
</Ellipse>
</Grid>
You should copy and try this exact code, try scanning it for some differences from your original code.
I am trying to have a polygon move from completely off the left of the screen, across the screen, and then completely off the right of the screen, then back again.
I've gotten this working. BUT, for some reason, as soon as the left margin becomes negative, the animation suddenly slows down. As soon as the left margin becomes positive, it speeds up again.
Why does this happen? How can I stop it?
Here's the complete code that demonstrates this:
<Window x:Class="Geometry.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>
<PathGeometry x:Key="MyGeometry">
<PathGeometry.Figures>
<PathFigure>
<PathFigure.Segments>
<LineSegment Point="0.30,0" />
<LineSegment Point="0.70,1" />
<LineSegment Point="0.40,1" />
<LineSegment Point="0,0" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
<Storyboard x:Key="MovingAnimation">
<ThicknessAnimationUsingKeyFrames RepeatBehavior="1:0:0" FillBehavior="HoldEnd" Storyboard.TargetName="_path" Storyboard.TargetProperty="Margin" >
<DiscreteThicknessKeyFrame KeyTime="0:0:0" Value="-2.0,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:10" Value="1.0,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:20" Value="-2.0,0,0,0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource MovingAnimation}" ></BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Label>Margin:</Label>
<TextBlock Text="{Binding ElementName=_path, Path=Margin.Left, StringFormat={}{0:0.#}}" />
</StackPanel>
<Canvas Name="_canvas" Grid.Row="1">
<Border Margin="0" Width="1" Height="1" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.RenderTransform>
<ScaleTransform
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</Border.RenderTransform>
<Path
Name="_path"
Fill="#CCCCFF"
Data="{StaticResource MyGeometry}"
Width="1.0"
Height="1.0"
>
</Path>
</Border>
</Canvas>
</Grid>
</Window>
I don't have an explanation why the negative margin animates slowly, but I found a workaround.
Instead of animating the Margin of the Path I animated the X value of a TranslateTransform on the Border object that contains the path.
I had to put the TranslateTransform in front of the ScaleTransform so that the translation was applied before the scale. That allows you to use almost the same values in your animation that you used for the Margin.
<Storyboard x:Key="MovingAnimation">
<ThicknessAnimationUsingKeyFrames RepeatBehavior="1:0:0" Storyboard.TargetName="_blank" Storyboard.TargetProperty="Margin" >
<LinearThicknessKeyFrame KeyTime="0:0:0" Value="-1.5,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:10" Value="1,0,0,0" />
<LinearThicknessKeyFrame KeyTime="0:0:20" Value="-1.5,0,0,0" />
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
The ugly part is that I couldn't find a quick way to apply the values in the key frames directly to the X property of the TranslateTransform, so I cheated and used element binding and a placeholder Canvas object.
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="5">
<TextBlock Margin="0,0,5,0" Text="Margin.Left:"/>
<TextBlock Text="{Binding ElementName=_blank, Path=Margin.Left, StringFormat={}{0:0.#}}" />
</StackPanel>
<Canvas Name="_blank" /> <!--Placeholder object-->
<Canvas Name="_canvas" Grid.Row="1">
<Border Margin="0" Width="1" Height="1"
Name="_border"
VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform X="{Binding Margin.Left, ElementName=_blank}"/>
<ScaleTransform
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</TransformGroup>
</Border.RenderTransform>
Even thought the animation is still being applied to a Margin and then to a TranslateTransform through element binding, the delay for a negative margin is gone.
I suspect that the negative margin delay has something to do with the Path being in the Border that was being scaled, but that is conjecture on my part.
If you can find a way to bind the KeyFrame values directly to the X property of the TranslateTransform, that would make this workaround much less ugly.
EDIT:
Figured out the proper binding to use:
<Storyboard x:Key="MovingAnimation2">
<DoubleAnimationUsingKeyFrames RepeatBehavior="1:0:0" Storyboard.TargetName="tt" Storyboard.TargetProperty="X" >
<LinearDoubleKeyFrame KeyTime="0:0:0" Value="-1.5" />
<LinearDoubleKeyFrame KeyTime="0:0:5" Value="1" />
<LinearDoubleKeyFrame KeyTime="0:0:10" Value="-1.5" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
This gets rid of the extra canvas placeholder object.
<Canvas Name="_canvas" Grid.Row="1">
<Border Margin="0" Width="1" Height="1"
Name="_border"
VerticalAlignment="Center" HorizontalAlignment="Center">
<Border.RenderTransform>
<TransformGroup>
<TranslateTransform x:Name="tt"/>
<ScaleTransform
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</TransformGroup>
</Border.RenderTransform>
Animating Margin property will trigger additional measure/arrange pass which in turn cause a bit more performance impact (though in this example it may not be noticeable). Animation of "render-only" properties on the other hand will not trigger layout re-arrangement and, thus, is more performance friendly.
Please, take a look at a bit easier way to do what, I suppose, you are want to get:
<Window x:Class="Geometry.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="518" Width="530">
<Window.Resources>
<PathGeometry x:Key="MyGeometry">
<PathGeometry.Figures>
<PathFigure>
<PathFigure.Segments>
<LineSegment Point="0.30,0" />
<LineSegment Point="0.70,1" />
<LineSegment Point="0.40,1" />
<LineSegment Point="0,0" />
</PathFigure.Segments>
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
<Storyboard x:Key="MovingAnimation">
<DoubleAnimationUsingKeyFrames RepeatBehavior="1:0:0" FillBehavior="HoldEnd" Storyboard.TargetName="_scaleTransform" Storyboard.TargetProperty="CenterX" >
<LinearDoubleKeyFrame KeyTime="0:0:0" Value="1.2" />
<LinearDoubleKeyFrame KeyTime="0:0:10" Value="-0.5" />
<LinearDoubleKeyFrame KeyTime="0:0:20" Value="1.2" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard Storyboard="{StaticResource MovingAnimation}" ></BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Label>Margin:</Label>
<TextBlock Text="{Binding ElementName=_scaleTransform, Path=CenterX, StringFormat={}{0:0.#}}" VerticalAlignment="Center" />
</StackPanel>
<!--
<Border Grid.Row="1" Margin="150" BorderBrush="Red" BorderThickness="1">
-->
<Grid Name="_canvas" Grid.Row="1">
<Path Name="_path" Fill="#CCCCFF" Data="{StaticResource MyGeometry}"
Width="1.0"
Height="1.0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Path.RenderTransform>
<ScaleTransform x:Name="_scaleTransform"
ScaleX="{Binding ElementName=_canvas, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvas, Path=ActualHeight}"
CenterX="1.2"
CenterY="0.5">
</ScaleTransform>
</Path.RenderTransform>
</Path>
</Grid>
<!--
</Border>
-->
</Grid>
</Window>
From the two answers so far, it's clear that if you want to have a shape fly around the screen, don't animate the margins.
Stewbob solved the problem by animating the X value of a translate transform.
sevenate solved the problem by animating the Center X value of a scale transform.
Another solution is, instead of wrapping the polygon in a border and animating the margin, wrap it up in a canvas and animate the left value.
Wrapping it in a canvas:
<Canvas Name="_canvasFrame" Grid.Row="1">
<Canvas Margin="0" Width="1" Height="1">
<Canvas.RenderTransform>
<ScaleTransform
ScaleX="{Binding ElementName=_canvasFrame, Path=ActualWidth}"
ScaleY="{Binding ElementName=_canvasFrame, Path=ActualHeight}"
CenterX="0"
CenterY="0">
</ScaleTransform>
</Canvas.RenderTransform>
<Path
Name="_path"
Fill="#CCCCFF"
Data="{StaticResource MyGeometry}"
Width="1.0" Height="1.0"
>
</Path>
</Canvas>
</Canvas>
Then animating the left value:
<Storyboard x:Key="MovingAnimation">
<DoubleAnimationUsingKeyFrames
RepeatBehavior="1:0:0"
FillBehavior="HoldEnd"
Storyboard.TargetName="_path"
Storyboard.TargetProperty="(Canvas.Left)" >
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="-1.0" />
<LinearDoubleKeyFrame KeyTime="0:0:10" Value="1.0" />
<LinearDoubleKeyFrame KeyTime="0:0:20" Value="-1.0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
I have a UserControl that is 45x45 (hardcoded size - it's part of a grid of items). When a certain property has a value I want to show a "clip" in the upper right-hand corner indicating this. The visibility itself is easy to accomplish, however my Rectangle goes outside the bounds of the control and overlaps on other controls. I tried using the "ClipToBounds" property, but it didn't do anything. When I added that to the overall control the clip worked perfectly but my hover effects on the main rectangle (fills the cell) stopped working.
Any ideas? I'm confident this is simple to do, but still being pretty new to WPF (and horrible at geometry - hence not using the Polygon) I'm a bit lost.
Here is the full markup:
<Grid>
<Rectangle x:Name="MainRectangle" Fill="{Binding Background}" Opacity="0" MouseEnter="MainRectangle_MouseEnter" MouseLeave="MainRectangle_MouseLeave">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.0" To="0.8" Duration="0:0:0.33" AutoReverse="False" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Rectangle.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.8" To="0.0" Duration="0:0:0.33" AutoReverse="False" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding VisualCount}" />
<Rectangle Fill="Black" HorizontalAlignment="Right" Height="20" Margin="0,-14,-20,0" Stroke="Black" VerticalAlignment="Top" Width="20" Visibility="{Binding HasNotes}">
<Rectangle.RenderTransform>
<RotateTransform CenterX="0" CenterY="0" Angle="45" />
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
Here be a simple path:
<Path Fill="Black" HorizontalAlignment="Right" Visibility="{Binding HasNotes}">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="0,0">
<LineSegment Point="14,0"/>
<LineSegment Point="14,14"/>
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>