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>
Related
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.
How can I constrain a plane projection to a particular dimension? For example, I have the following:
<Canvas Width="720" Height="540" x:Name="Root" Background="Red" >
<Line Width="200" Height="5" X1="0" X2="200"
Y1="0" Y2="0" Stroke="LimeGreen" StrokeThickness="10"
Canvas.Left="260" Canvas.Top="70" />
<Rectangle Width="200" Height="400" Stroke="Blue" StrokeThickness="6"
Fill="LightBlue" Opacity="0.5" Canvas.Left="260" Canvas.Top="70">
<Rectangle.Projection>
<PlaneProjection x:Name="box" />
</Rectangle.Projection>
</Rectangle>
<Line Width="200" Height="10" X1="0" X2="200"
Y1="0" Y2="0" Stroke="LimeGreen" StrokeThickness="10"
Canvas.Left="260" Canvas.Top="464" />
</Canvas>
I want to rotate this around its Y axis by 360 degrees, but never want the projection to exceed the bounds of the height of the rectangle - in this case, 400 points.
The storyboard, just for simplicities' sake in testing, is in a trigger.
<UserControl.Triggers>
<EventTrigger>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="box"
Storyboard.TargetProperty="RotationY"
By="360" Duration="0:0:15"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</UserControl.Triggers>
This is not perfect, as it is linear interpolation and the actual relationship of the height to angle of rotation is a slight sinusoidal curve, but is close to what you want.
It basically scales Y to 0.88 in one quarter of the total time (and is AutoReversed).
You can simplify the element naming as you did with "box" if you prefer (I used Blend to author/test the storyboard and it always creates the long element names):
<Storyboard>
<DoubleAnimation Storyboard.TargetName="box"
Storyboard.TargetProperty="RotationY"
By="360" Duration="0:0:15"
RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)"
Storyboard.TargetName="rectangle"
Duration="0:0:3.75" To="0.88"
RepeatBehavior="Forever"
AutoReverse="True" >
</DoubleAnimation>
</Storyboard>
<Rectangle x:Name="rectangle"
Stroke="Blue"
StrokeThickness="6"
Fill="LightBlue"
Opacity="0.5"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<CompositeTransform/>
</Rectangle.RenderTransform>
<Rectangle.Projection>
<PlaneProjection x:Name="box" />
</Rectangle.Projection>
</Rectangle>
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>
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 :)
(Note: I have seen this question and it uses a cursor not an animation.)
I have a wait animation (that I did not make but found on the internet). I want to show it while my app is doing some processing.
However, it gets stuck while my app is processing. Is there a way to make it keep going smooth? I usually think of a thread for this, but there are a few problems with that.
I have no idea how to fire off a thread in XAML
I usually know enough about threading to just get myself seriously messed up.
I have done very little threading code in .NET
Can any one help me out? Here is the XAML that creates the wait animation:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Viewbox Name="WaitCursor" >
<Canvas Width="80" Height="80" Name="canvas">
<Canvas.RenderTransform>
<RotateTransform Angle="0" CenterX="40" CenterY="40" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="canvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(RotateTransform.Angle)"
To="360"
Duration="0:0:0.7"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Canvas.Triggers>
<Ellipse Canvas.Top="0" Canvas.Left="30" Width="20" Height="20" >
<Ellipse.Fill>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="10" R="0" G="0" B="255" />
</SolidColorBrush.Color>
</SolidColorBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Canvas.Top="10" Canvas.Left="50" Width="20" Height="20" Fill="#15000000"/>
<Ellipse Canvas.Top="30" Canvas.Left="60" Width="20" Height="20" Fill="#38000000"/>
<Ellipse Canvas.Top="50" Canvas.Left="50" Width="20" Height="20" Fill="#55000000"/>
<Ellipse Canvas.Top="60" Canvas.Left="30" Width="20" Height="20" Fill="#88000000"/>
<Ellipse Canvas.Top="50" Canvas.Left="10" Width="20" Height="20" Fill="#aa000000"/>
<Ellipse Canvas.Top="30" Canvas.Left="0" Width="20" Height="20" Fill="#cc000000"/>
<Ellipse Canvas.Top="10" Canvas.Left="10" Width="20" Height="20" Fill="#ff000000"/>
</Canvas>
</Viewbox>
</Grid>
</Page>
For those who need an actual code example, I plan to put this in the OnClick event of the "Link" Button found in this CodePlex Project.
Your best bet is to use a BackgroundWorker. It will do the work of marshaling to the correct thread on your behalf.