I want to create a slideshow of images. For this I have loaded new images in image control after every set interval of time. But each time i load a new image it comes without any animation I need to load each image with a transition animation or fade in-out animation. How can I achieve animation while changing images in Image control? Following is the code:
XAML:
<Grid>
<Image Source="{Binding CurrentImage}" />
</Grid>
XAML.cs
ViewModel = new ScreenSaverViewModel();
this.DataContext = ViewModel;
ViewModel.cs
/// <summary>
/// Gets the current image to display on the attract screen. Changes to this property
/// cause the PropertyChanged event to be signaled
/// </summary>
public string CurrentImage
{
get { return this.currentImage; }
protected set
{
this.currentImage = value;
this.OnPropertyChanged("CurrentImage");
}
}
/// <summary>
/// Gets the observable collection of all images.
/// </summary>
public ObservableCollection<string> Images
{
get { return this.images; }
}
public ScreenSaverViewModel()
{
images = new ObservableCollection<string>();
this.LoadSlideShowImages();
if (Images != null && Images.Count > 0)
{
this.CurrentImage = this.Images[this.currentIndex];
this.tickTimer = new DispatcherTimer();
this.tickTimer.Interval = TimeSpan.FromMilliseconds(TimerIntervalMilliseconds);
this.tickTimer.Tick += (s, e) =>
{
this.currentIndex++;
this.currentIndex = this.currentIndex < this.Images.Count ? this.currentIndex : 0;
this.CurrentImage = this.Images[this.currentIndex];
};
// start the timer after image is loaded
this.tickTimer.Start();
}
}
I have created a class inheriting Image control in which I have raised property change when Source of image control changes. on which I have applied trigger this works fine now. Following is the code:
<controls:ImageControl Source="{Binding CurrentImage}" >
<controls:ImageControl.Triggers>
<EventTrigger RoutedEvent="controls:ImageControl.SourceChanged">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)" From="0" To="1" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</controls:ImageControl.Triggers>
</controls:ImageControl>
public class ImageControl : Image
{
public static readonly RoutedEvent SourceChangedEvent = EventManager.RegisterRoutedEvent(
"SourceChanged", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(ImageControl));
static ImageControl()
{
Image.SourceProperty.OverrideMetadata(typeof(ImageControl), new FrameworkPropertyMetadata(SourcePropertyChanged));
}
public event RoutedEventHandler SourceChanged
{
add { AddHandler(SourceChangedEvent, value); }
remove { RemoveHandler(SourceChangedEvent, value); }
}
private static void SourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
Image image = obj as Image;
if (image != null)
{
image.RaiseEvent(new RoutedEventArgs(SourceChangedEvent));
}
}
}
Hope this helps.
Please run this code separately.
<Grid Height="200" Width="200">
<Grid.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard >
<Storyboard >
<ObjectAnimationUsingKeyFrames Duration="00:00:06" RepeatBehavior="Forever" Storyboard.TargetName="img1" Storyboard.TargetProperty="(Image.Source)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="image1.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:02">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="image2.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="00:00:04">
<DiscreteObjectKeyFrame.Value>
<BitmapImage UriSource="image3.png" />
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetName="img1" RepeatBehavior="Forever" Storyboard.TargetProperty="Opacity" From="0.1" To="1" Duration="00:00:02"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Image x:Name="img1" Stretch="Fill"></Image>
</Grid>
Update
<Storyboard FillBehavior="Stop" x:Key="FadeOut">
<DoubleAnimation FillBehavior="Stop" Storyboard.TargetName="ScreensaverImage" Storyboard.TargetProperty="Opacity" From="0.05" To="1" Duration="0:0:2">
</DoubleAnimation>
</Storyboard>
<Storyboard FillBehavior="Stop" x:Key="FadeIn">
<DoubleAnimation Storyboard.TargetName="ScreensaverImage" FillBehavior="Stop" Storyboard.TargetProperty="Opacity" From="1" To=".05" Duration="0:0:2">
</DoubleAnimation>
</Storyboard>
<Grid>
<Image x:Name="ScreensaverImage"></Image>
</Grid>
public partial class MainWindow : Window
{
List<Uri> savedImage = new List<Uri>();
int i = 0;
Storyboard fadeIn, fadeOut;
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
savedImage.Add(new Uri("image1.png", UriKind.Relative));
savedImage.Add(new Uri("image2.png", UriKind.Relative));
savedImage.Add(new Uri("image3.png", UriKind.Relative));
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
if (savedImage.Count > 0)
{
fadeIn = (Storyboard)this.Resources["FadeIn"];
fadeOut = (Storyboard)this.Resources["FadeOut"];
fadeIn.Completed += fadeIn_Completed;
fadeOut.Completed += fadeOut_Completed;
ScreensaverImage.Source = new BitmapImage(savedImage[i++]);
if (savedImage.Count > 1)
{
BeginStoryboard(fadeOut);
}
ScreensaverImage.Visibility = System.Windows.Visibility.Visible;
}
else
{
ScreensaverImage.Visibility = System.Windows.Visibility.Collapsed;
}
}
void fadeOut_Completed(object sender, EventArgs e)
{
fadeIn.Begin();
}
void fadeIn_Completed(object sender, EventArgs e)
{
if (i == savedImage.Count)
i = 0;
ScreensaverImage.Source = new BitmapImage(savedImage[i++]);
fadeOut.Begin();
}
}
you can use the MetroImageControl or MetroContentControl that provided in:
Mahapps library for metro style
Related
I made an Application where I add many Grids to some Stackpanels in a for loop. My problem is that, while the for loop is loading my Application doesn´t respond and my Loadinganimation is freezed. How can I add the Grids to the Stackpanel without affecting the UI Thread, so my Loading Animation won´t freeze.
Thanks in Advance
Edit:
Grid creation Method:
public void GridExample()
{
for(int i = 0; i < 120; i++)
{
Grid Grid1 = new Grid();
Grid1.FlowDirection = FlowDirection.LeftToRight;
Grid1.Width = 200;
Grid1.Background = new SolidColorBrush(Color.FromArgb(255, (byte)33, (byte)33, (byte)33));
Grid1.Margin = new Thickness(5, 20, 5, 20);
ColumnDefinition Grid1_col1 = new ColumnDefinition();
Grid1.ColumnDefinitions.Add(Grid1_col1);
RowDefinition Grid1_row1 = new RowDefinition();
RowDefinition Grid1_row2 = new RowDefinition();
RowDefinition Grid1_row3 = new RowDefinition();
RowDefinition Grid1_row4 = new RowDefinition();
Grid1.RowDefinitions.Add(Grid1_row1);
Grid1.RowDefinitions.Add(Grid1_row2);
Grid1.RowDefinitions.Add(Grid1_row3);
Grid1.RowDefinitions.Add(Grid1_row4);
Grid1_row1.Height = new GridLength(255);
Grid1_row2.Height = new GridLength(60);
Grid1_row3.Height = new GridLength(5);
Grid1_row4.Height = new GridLength(55);
//Adds Grid to HomePage
homepage1_mainstackpanel1.Children.Add(Grid1);
Image Image1 = new Image();
Image1.Stretch = Stretch.Fill;
Image1.Source = new BitmapImage(new Uri("Image.png"));
Grid.SetRow(Image1, 0);
Grid1.Children.Add(Image1);
Label Label1 = new Label();
Label1.Content = "Example Text";
Label1.FontSize = 15;
Label1.Foreground = new SolidColorBrush(Colors.White);
Label1.VerticalAlignment = VerticalAlignment.Center;
Label1.HorizontalAlignment = HorizontalAlignment.Center;
Grid.SetRow(Label1, 1);
Grid1.Children.Add(Label1);
Line Line1 = new Line();
Line1.X1 = 1;
Line1.StrokeThickness = 2;
Line1.Stroke = new SolidColorBrush(Color.FromArgb(255, (byte)51, (byte)51, (byte)51));
Line1.Stretch = Stretch.Fill;
Grid.SetRow(Line1, 2);
Grid1.Children.Add(Line1);
Button Button1 = new Button();
Button1.Content = "Play";
Button1.FontSize = 15;
Button1.Foreground = new SolidColorBrush(Colors.White);
Button1.Background = new SolidColorBrush(Color.FromArgb(255, (byte)33, (byte)33, (byte)33));
Button1.BorderThickness = new Thickness(0);
Button1.VerticalAlignment = VerticalAlignment.Center;
Button1.HorizontalAlignment = HorizontalAlignment.Center;
Button1.Click += new RoutedEventHandler((sender, e) =>
{
this.NavigationService.Navigate(new WatchPage1());
});
Grid1.Children.Add(Button1);
}
}
Loading Animation in HomePage:
public static Dispatcher mainthread_dispatcher = Dispatcher.CurrentDispatcher;
public HomePage1()
{
Loaded += Page_loaded;
InitializeComponent();
}
private void Page_loaded(object sender, RoutedEventArgs e)
{
using (LoadingAnimation loadanimation = new LoadingAnimation(GridExample))
{
loadanimation.ShowDialog();
}
}
LoadingAnimation.xaml:
<Window x:Class="Spaceflix_Desktop.LoadingAnimation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Spaceflix_Desktop"
mc:Ignorable="d"
Height="110" Width="90" Loaded="Animation_Loaded">
<Window.Resources>
<Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse1">
<EasingColorKeyFrame KeyTime="0" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#B25B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse2">
<EasingColorKeyFrame KeyTime="0" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#FF5B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse3">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse4">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse5">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse6">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse7">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse8">
<EasingColorKeyFrame KeyTime="0" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#7F5B5B5B"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Border x:Name="Border" BorderBrush="#c62828" BorderThickness="2" Background="Black" Height="80" Width="80">
<Grid x:Name="maingrid" Background="Transparent">
<Ellipse x:Name="ellipse1" Fill="#FF5B5B5B" HorizontalAlignment="Center" Margin="0, 5, 0, 0" Height="15" VerticalAlignment="Top" Width="15"/>
<Ellipse x:Name="ellipse2" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 15, 15, 0" Height="15" VerticalAlignment="Top" Width="15"/>
<Ellipse x:Name="ellipse3" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 0, 5, 0" Height="15" VerticalAlignment="Center" Width="15"/>
<Ellipse x:Name="ellipse4" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 0, 15, 15" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse5" Fill="#FF5B5B5B" HorizontalAlignment="Center" Margin="0, 0, 0, 5" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse6" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="15, 0, 0, 15" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse7" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="5, 0, 0, 0" Height="15" VerticalAlignment="Center" Width="15"/>
<Ellipse x:Name="ellipse8" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="15, 15, 0, 0" Height="15" VerticalAlignment="Top" Width="15"/>
</Grid>
</Border>
</Window>
LoadingAnimation.cs:
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using System.Runtime.Remoting.Channels;
using System.Windows.Media.Media3D;
using System.Windows.Interop;
namespace Test_Application
{
/// <summary>
/// Interaktionslogik für LoadingAnimation.xaml
/// </summary>
public partial class LoadingAnimation : Window, IDisposable
{
public Action Worker { get; set; }
public LoadingAnimation (Action worker)
{
InitializeComponent();
Worker = worker ?? throw new ArgumentNullException();
}
public void Animation_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() => { }).ContinueWith(t => HomePage1.mainthread_dispatcher.Invoke(() => Worker()), TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith(t => Dispatcher.Invoke(() => Close()));
}
public void Dispose()
{
}
}
}
I hope this Information are enough
after I didn't have time for this project for a long time, I've now dealt with it again and found a solution. I can't add the grids to the stack panels in a new task or thread but at least I can display the loading animation smoothly. Because the grids have to be added to the main thread, I ran the loading animation in a new thread. So I had to display it as a popup. This is the best solution I found.
Here is the Code from the HomePage:
var PositionWindow = (Window)Parent;
int CenterX = 8;
int CenterY = 1;
Point CenterPoints = new Point(PositionWindow.Left + CenterX + (PositionWindow.Width / 2), PositionWindow.Top + CenterY + (PositionWindow.Height / 2));
Thread LoadThread = new Thread(new ThreadStart(() => {
using (PopUpLoadingAnimation loadanimation = new PopUpLoadingAnimation(GridExample, CenterPoints, PositionWindow))
{
loadanimation.StartTask();
Dispatcher.Run();
}
}));
LoadThread.SetApartmentState(ApartmentState.STA);
LoadThread.Start();
I had to calculate the middle of the Window by myself to make the PopUp centered.
And here is the Code of the PopUpLoadingAnimation.cs:
public partial class PopUpLoadingAnimation : Popup
{
public Action Worker { get; set; }
private Point _PlacementPoints { get; set; }
private Window MainWindow { get; set; }
public PopUpLoadingAnimation (Action worker, Point PlacementPoints, Window mainthreadwindow)
{
InitializeComponent();
Worker = worker ?? throw new ArgumentNullException();
MainWindow = mainthreadwindow;
_PlacementPoints = PlacementPoints;
}
public void StartTask()
{
Task.Factory.StartNew(() => Dispatcher.Invoke(() =>
{
Storyboard animationboard = Resources["Storyboard1"] as Storyboard;
animationboard.Begin(maingrid);
LoadingPopup.Placement = PlacementMode.Center;
LoadingPopup.HorizontalOffset = _PlacementPoints.X;
LoadingPopup.VerticalOffset = _PlacementPoints.Y;
LoadingPopup.IsOpen = true;
HomePage1.mainthread_dispatcher.Invoke(() => MainWindow.IsEnabled = false);
})).ContinueWith(t => HomePage1.mainthread_dispatcher.Invoke(() => Worker()), HomePage1.mainthread_scheduler).ContinueWith(t => Dispatcher.Invoke(async () =>
{
LoadingPopup.IsOpen = false;
HomePage1.mainthread_dispatcher.Invoke(() => MainWindow.IsEnabled = true);
Dispatcher.InvokeShutdown();
}));
}
by the way thanks for the answers, unfortunately they did not help
I have creaed flipview in XAML page i want to make that slides transtaction automatically how can i do that?
<StackPanel x:Name="StackPanel_1" Margin="541,42,71,160" Orientation="Vertical" Grid.Row="1">
<FlipView x:Name="flipView1" Width="480" Height="270"
BorderBrush="Black" BorderThickness="1">
<Grid Margin="0,0,-8,-8">
<Image Source="Assets/Logo.png" Width="480" Height="270" Stretch="UniformToFill"/>
<Border Background="#A5000000" Height="80" VerticalAlignment="Bottom">
<TextBlock Text="Logo" FontFamily="Segoe UI" FontSize="26.667" Foreground="#CCFFFFFF" Padding="15,20" Margin="0,0,8,8"/>
</Border>
</Grid>
<Grid Margin="0,0,-8,-8">
<Image Source="Assets/SplashScreen.png" Width="480" Height="270" Stretch="UniformToFill" />
<Border Background="#A5000000" Height="80" VerticalAlignment="Bottom">
<TextBlock Text="Logo11111111" FontFamily="Segoe UI" FontSize="26.667" Foreground="#CCFFFFFF" Padding="15,20" Margin="0,0,8,8"/>
</Border>
</Grid>
<Grid Height="270" Width="480">
<Image Source="Assets/SmallLogo.png" Width="480" Height="270" Stretch="UniformToFill" />
<Border Background="#A5000000" Height="80" VerticalAlignment="Bottom">
<TextBlock Text="Logo222222222" FontFamily="Segoe UI" FontSize="26.667" Foreground="#CCFFFFFF" Padding="15,20" Margin="0,0,8,8"/>
</Border>
</Grid>
</FlipView>
You'll need to update the flipview's SelectedIndex property.
The most straightforward would be to run a DispatcherTimer and increment SelectedIndex every however long you'd like. When it gets to the end then set it back to 0. The hitch is that the FlipView will animate when you switch the index by one, but not when you jump pages. If you want to loop back from the last page to the first it will jump rather than animate. You might want to reverse direction instead of going direct to 0.
int change = 1;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(2);
timer.Tick += (o, a) =>
{
// If we'd go out of bounds then reverse
int newIndex = flipView1.SelectedIndex + change;
if (newIndex >= flipView1.Items.Count || newIndex < 0)
{
change *= -1;
}
flipView1.SelectedIndex += change;
};
timer.Start();
If you want to set this up completely in XAML without code then you can create a Storyboarded animation in Xaml to animate the SelectedIndex and trigger it with an EventTriggerBehavior behavior when page loads.
<Page.Resources>
<Storyboard x:Name="AutoFlipView" RepeatBehavior="Forever" AutoReverse="True">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Selector.SelectedIndex)" Storyboard.TargetName="flipView1">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<x:Int32>0</x:Int32>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:1">
<DiscreteObjectKeyFrame.Value>
<x:Int32>1</x:Int32>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:2">
<DiscreteObjectKeyFrame.Value>
<x:Int32>2</x:Int32>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
<DiscreteObjectKeyFrame KeyTime="0:0:3">
<DiscreteObjectKeyFrame.Value>
<x:Int32>2</x:Int32>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Loaded">
<Media:ControlStoryboardAction Storyboard="{StaticResource AutoFlipView}"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
I wrote a hacky prototype that shows how you can animate the entire cycle by rearranging the elements in the FlipView...
C#
using System.Collections;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace App4
{
public class CyclingFlipView : FlipView
{
public async Task Cycle()
{
if (this.ItemsSource != null)
{
var list = (IList)this.ItemsSource;
if (list.Count == 0)
{
return;
}
SelectionChangedEventHandler handler = null;
var tcs = new TaskCompletionSource<bool>();
handler = (s, e) =>
{
tcs.SetResult(true);
this.SelectionChanged -= handler;
};
this.SelectionChanged += handler;
this.SelectedIndex = (this.SelectedIndex + 1) % list.Count;
await tcs.Task;
await Task.Delay(500);
var i = this.SelectedIndex;
this.SelectedItem = null;
var item = list[0];
list.RemoveAt(0);
list.Add(item);
this.SelectedIndex = i - 1;
}
else if (this.Items != null)
{
if (this.Items.Count == 0)
{
return;
}
SelectionChangedEventHandler handler = null;
var tcs = new TaskCompletionSource<bool>();
handler = (s, e) =>
{
tcs.SetResult(true);
this.SelectionChanged -= handler;
};
this.SelectionChanged += handler;
this.SelectedIndex = (this.SelectedIndex + 1) % this.Items.Count;
await tcs.Task;
await Task.Delay(500);
var i = this.SelectedIndex;
this.SelectedItem = null;
var item = this.Items[0];
this.Items.RemoveAt(0);
this.Items.Add(item);
this.SelectedIndex = i - 1;
}
}
public async Task AutoCycle()
{
while (true)
{
this.Cycle();
await Task.Delay(1000);
}
}
}
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
var fv = new CyclingFlipView();
fv.ItemsSource = new ObservableCollection<int>(Enumerable.Range(0, 4));
fv.ItemTemplate = (DataTemplate)this.Resources["ItemTemplate"];
this.Content = fv;
fv.AutoCycle();
}
}
}
XAML
<Page
x:Class="App4.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App4"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<DataTemplate
x:Key="ItemTemplate">
<Border
Background="GreenYellow">
<TextBlock
Text="{Binding}"
FontSize="144"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Border>
</DataTemplate>
</Page.Resources>
<Grid
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
</Grid>
</Page>
How can I convert this piece of XAML code to code-behind in C# as my from and to value changes dynamically?
XAML
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="00:00:00"
From="200"
To="500"
Storyboard.TargetProperty="(Window.Top)"
AccelerationRatio=".1"
Duration="0:0:.2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
You don't need Storyboard from code behind, that can be done only with DoubleAnimation.
public MainWindow()
{
InitializeComponent();
Loaded += (s, e) =>
{
DoubleAnimation animation = new DoubleAnimation(200, 500,
TimeSpan.FromSeconds(0.2));
animation.AccelerationRatio = 0.1;
BeginAnimation(Window.TopProperty, animation);
};
}
Try this:
XAML
<Window x:Class="CreateAnimationinCodeHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="MyWindow" Loaded="Window_Loaded"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Label Background="AliceBlue" Content="Test" />
</Grid>
</Window>
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Storyboard sb = new Storyboard();
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = 200;
doubleAnimation.To = 500;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.2));
doubleAnimation.AccelerationRatio = 0.1;
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Window.Top)"));
sb.Children.Add(doubleAnimation);
MyWindow.BeginStoryboard(sb);
}
}
I am trying to achieve a simple label scroller(found the idea here: Scroller StackOverflow. I have a label, which I want to animate with help of DoubleAnimation class like this:
In constructor I implement event for Loaded:
public Web()
{
InitializeComponent();
SetDefaultBrowser();
SetDefaultWebsite();
//TextBlockSong.Text = GetSongName(GetBrowserName(), GetWebsiteName());
Loaded += Window1_Loaded;
}
Event:
void Window1_Loaded(object sender, RoutedEventArgs e)
{
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = -LabelNameSong.ActualWidth;
doubleAnimation.To = canMain.ActualWidth;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.Parse("0:0:10"));
LabelNameSong.BeginAnimation(Canvas.RightProperty, doubleAnimation);
}
Everything works until I update my LabelNameSong content. The LabelNameSong width stays the same as before, and my animation doesn't work properly from the start anymore(with updated text).
I update my LabelNameSong with ListBox_SelectionChanged event:
private void ListBoxWebsite_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
double k = LabelNameSong.Width;
double z = LabelNameSong.ActualWidth;
LabelWebsiteName.Content = "Now on " + GetWebsiteName();
LabelNameSong.Content = GetSongName(GetBrowserName(), GetWebsiteName());
k = LabelNameSong.Width;
z = LabelNameSong.ActualWidth;
}
I used those to measure width, and found out that it doesn't update the width of LabelNameSong. I am new here, don't even know if it should.
This is my xaml:
<Canvas Background="White" Margin="0,182,58,0" >
<Canvas ClipToBounds="True" Name="canMain" Height="80" Width="346" >
<Label FontSize="25" Foreground="#666666" Name="LabelNameSong" Canvas.Top="27" Height="30" Width="Auto" Content="This is very long text, I am testing it!" FontFamily="Calibri Light"/>
</Canvas>
</Canvas>
So my question is, what could I do to update the width of my LabelNameSong, and how should I re-call Window1_Loaded event so new instance of DoubleAnimation would work with updated ActualWidth?
doubleAnimation.From = -LabelNameSong.ActualWidth;
doubleAnimation.To = canMain.ActualWidth;
Thank you.
You can just wrap the Animation logic into a method and call from Loaded event and any other event you need
private void CreateAnimation()
{
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = -LabelNameSong.ActualWidth;
doubleAnimation.To = canMain.ActualWidth;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.Parse("0:0:10"));
LabelNameSong.BeginAnimation(Canvas.RightProperty, doubleAnimation);
}
void Window1_Loaded(object sender, RoutedEventArgs e)
{
CreateAnimation();
}
private void LabelNameSong_SizeChanged(object sender, RoutedEventArgs e)
{
CreateAnimation();
}
But you can probably do it all in Xaml using Triggers and get rid of all that code behind.
In the example below the animation will start on Load and restart when the Size changes
Example:
<Label x:Name="LabelNameSong" Content="Hello" >
<Label.Resources>
<Storyboard x:Key="scroll">
<DoubleAnimation To="{Binding ActualWidth, ElementName=LabelNameSong}" Duration="00:00:10"
Storyboard.TargetProperty="(Canvas.Right)"
Storyboard.TargetName="LabelNameSong"
RepeatBehavior="Forever"/>
</Storyboard>
</Label.Resources>
<Label.Triggers>
<EventTrigger RoutedEvent="Label.Loaded">
<BeginStoryboard Storyboard="{StaticResource scroll}" />
</EventTrigger>
<EventTrigger RoutedEvent="Label.SizeChanged">
<BeginStoryboard Storyboard="{StaticResource scroll}" />
</EventTrigger>
</Label.Triggers>
</Label>
Can anyone point me to some code samples on how I could implement a gallery like the one in iOS where you can swipe side to side to change the image when using a touchscreen monitor on Windows 7?
You will need to implement swipe-like animations for this.
Guidelines for touch in WPF apps
I haven't tried this myself, but here is what seems to be an open source repo for a WPF carousel that might be worth taking a look at
Blog entry about swipe animation in WPF
Change the image on desired 'swipe-movement' :)
Free animation libraries if you don't want to create the animation yourself
Hope it helps!
Here is (by the way) the carousel control in the second link in case it goes missing like the previous one:
Code by Michael Palotas
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
namespace WPFDemo
{
public class CarouselControl : Canvas
{
public CarouselControl()
{
_timer.Tick += new EventHandler(TimerTick);
_timer.Interval = TimeSpan.FromMilliseconds(10);
}
public DateTime _previousTime;
public DateTime _currentTime;
public void ReInitialize()
{
Init();
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
Init();
}
public delegate void OnElementSelectedHandler(object sender);
public event OnElementSelectedHandler OnElementSelected;
public void SelectElement(FrameworkElement element)
{
if (element != null)
{
_previousTime = DateTime.Now;
RotateToElement(element);
if (OnElementSelected != null)
OnElementSelected(element);
}
}
private const double DEFAULT_ROTATION_SPEED = 200;
private const double MINIMUM_ROTATION_SPEED = 1;
private const double MAXIMUM_ROTATION_SPEED = 1000;
private double _rotationSpeed = DEFAULT_ROTATION_SPEED;
public double RotationSpeed
{
get
{
return _rotationSpeed;
}
set
{
_rotationSpeed = Math.Min(Math.Max(value, MINIMUM_ROTATION_SPEED), MAXIMUM_ROTATION_SPEED);
}
}
private const double DEFAULT_LOOKDOWN_OFFSET = 0;
private const double MINIMUM_LOOKDOWN_OFFSET = -100;
private const double MAXIMUM_LOOKDOWN_OFFSET = 100;
private double _lookdownOffset = DEFAULT_LOOKDOWN_OFFSET;
public double LookDownOffset
{
get
{
return _lookdownOffset;
}
set
{
_lookdownOffset = Math.Min(Math.Max(value, MINIMUM_LOOKDOWN_OFFSET), MAXIMUM_LOOKDOWN_OFFSET);
}
}
private const double DEFAULT_FADE = 0.5;
private const double MINIMUM_FADE = 0;
private const double MAXIMUM_FADE = 1;
private double _fade = DEFAULT_FADE;
public double Fade
{
get
{
return _fade;
}
set
{
_fade = Math.Min(Math.Max(value, MINIMUM_FADE), MAXIMUM_FADE);
}
}
private const double DEFAULT_SCALE = 0.5;
private const double MINIMUM_SCALE = 0;
private const double MAXIMUM_SCALE = 1;
private double _scale = DEFAULT_SCALE;
public double Scale
{
get
{
return _scale;
}
set
{
_scale = Math.Min(Math.Max(value, MINIMUM_SCALE), MAXIMUM_SCALE);
}
}
private void element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
SelectElement(sender as FrameworkElement);
}
private void RotateToElement(FrameworkElement element)
{
if (element != _currentlySelected)
{
_currentlySelected = element;
int targetIndex = Children.IndexOf(element);
double degreesToRotate = GetDegreesNeededToPlaceElementInFront(_currentRotation, targetIndex, TotalNumberOfElements);
_targetRotation = ClampDegrees(_currentRotation - degreesToRotate);
StartRotation(degreesToRotate);
}
}
internal static double GetDegreesNeededToPlaceElementInFront(double currentRotation, int targetIndex, int totalNumberOfElements)
{
double rawDegrees = -(180.0 - (currentRotation + 360.0 * ((double)targetIndex / (double)totalNumberOfElements)));
if (rawDegrees > 180)
return -(360 - rawDegrees);
return rawDegrees;
}
private double RotationAmount
{
get
{
return (_currentTime - _previousTime).TotalSeconds * _rotationSpeed;
}
}
private const double INTERNAL_SCALE_COEFFICIENT = 0.6;
private void Init()
{
_previousTime = _currentTime = DateTime.Now;
X_SCALE = CenterX * INTERNAL_SCALE_COEFFICIENT;
Y_SCALE = CenterY * INTERNAL_SCALE_COEFFICIENT;
foreach (FrameworkElement element in Children)
{
element.MouseLeftButtonDown += new MouseButtonEventHandler(element_MouseLeftButtonDown);
element.Cursor = Cursors.Hand;
}
SelectElement(GetChild(0));
SetElementPositions();
}
private FrameworkElement _currentlySelected = null;
public FrameworkElement CurrentlySelected { get { return _currentlySelected; } }
protected double CenterX { get { return this.Width / 2.0; } }
protected double CenterY { get { return this.Height / 2.0; } }
protected double X_SCALE = 0;
protected double Y_SCALE = 0;
protected DispatcherTimer _timer = new DispatcherTimer();
private double _rotationToGo = 0;
private int TotalNumberOfElements { get { return Children.Count; } }
protected double _currentRotation = 0;
protected double _targetRotation = 0;
protected virtual void TimerTick(object sender, EventArgs e)
{
_currentTime = DateTime.Now;
if ((_rotationToGo < RotationAmount) && (_rotationToGo > -RotationAmount))
{
_rotationToGo = 0;
if (_currentRotation != _targetRotation)
{
_currentRotation = _targetRotation;
}
else
{
_timer.Stop();
return;
}
}
else if (_rotationToGo < 0)
{
_rotationToGo += RotationAmount;
_currentRotation = ClampDegrees(_currentRotation + RotationAmount);
}
else
{
_rotationToGo -= RotationAmount;
_currentRotation = ClampDegrees(_currentRotation - RotationAmount);
}
SetElementPositions();
_previousTime = _currentTime;
}
protected double ClampDegrees(double rawDegrees)
{
if (rawDegrees > 360)
return rawDegrees - 360;
if (rawDegrees < 0)
return rawDegrees + 360;
return rawDegrees;
}
public void SetElementPositions()
{
for (int index = 0; index < TotalNumberOfElements; index++)
{
FrameworkElement element = GetChild(index);
double elementWidthCenter = GetElementCenter(element.Width, element.ActualWidth);
double elementHeightCenter = GetElementCenter(element.Height, element.ActualHeight);
double degrees = 360 * ((double)index / (double)TotalNumberOfElements) + _currentRotation;
double x = -X_SCALE * Math.Sin(ConvertToRads(degrees)) - (double.IsNaN(Y_SCALE) ? 0.0 : Y_SCALE / 100.0) * (Math.Cos(ConvertToRads(degrees)) * LookDownOffset);
Canvas.SetLeft(element, x + CenterX - elementWidthCenter);
double y = Y_SCALE * Math.Sin(ConvertToRads(degrees)) - (double.IsNaN(X_SCALE) ? 0.0 : X_SCALE / 100.0) * (Math.Cos(ConvertToRads(degrees)) * LookDownOffset);
Canvas.SetTop(element, y + CenterY - elementHeightCenter);
ScaleTransform scale = element.RenderTransform as ScaleTransform;
if (scale == null)
{
scale = new ScaleTransform();
element.RenderTransform = scale;
}
scale.CenterX = elementWidthCenter;
scale.CenterY = elementHeightCenter;
scale.ScaleX = scale.ScaleY = GetScaledSize(degrees);
Canvas.SetZIndex(element, GetZValue(degrees));
SetOpacity(element, degrees);
}
}
private FrameworkElement GetChild(int index)
{
if (Children.Count == 0)
return null;
FrameworkElement element = Children[index] as FrameworkElement;
if (element == null)
throw new NotSupportedException("Carousel only supports children that are Framework elements");
return element;
}
internal static double GetElementCenter(double elementDimension, double elementActualDimension)
{
return double.IsNaN(elementDimension) ? elementActualDimension / 2.0 : elementDimension / 2.0;
}
private void SetOpacity(FrameworkElement element, double degrees)
{
element.Opacity = (1.0 - Fade) + Fade * GetCoefficient(degrees);
}
private int GetZValue(double degrees)
{
return (int)(360 * GetCoefficient(degrees));
}
private double GetScaledSize(double degrees)
{
return (1.0 - Scale) + Scale * GetCoefficient(degrees);
}
private double GetCoefficient(double degrees)
{
return 1.0 - Math.Cos(ConvertToRads(degrees)) / 2 - 0.5;
}
private double ConvertToRads(double degrees)
{
return degrees * Math.PI / 180.0;
}
private void StartRotation(double numberOfDegrees)
{
_rotationToGo = numberOfDegrees;
if (!_timer.IsEnabled)
{
_timer.Start();
}
}
}
}
XAML:
<UserControl
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"
mc:Ignorable="d"
x:Class="WPFDemo.SphereControl"
x:Name="UserControl"
d:DesignWidth="50" d:DesignHeight="50">
<UserControl.Resources>
<Storyboard x:Key="MouseOver">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1.3" KeySpline="0,0,0.5,1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1.3" KeySpline="0,0,0.5,1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Ellipse" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Offset)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0.231"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Ellipse" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.312"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="0.729"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MouseLeave">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="1" KeySpline="0,0,0.5,1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="1" KeySpline="0,0,0.5,1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Ellipse" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Offset)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Ellipse" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Offset)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="0.312"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard Storyboard="{StaticResource MouseOver}" x:Name="MouseOver_BeginStoryboard"/>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard Storyboard="{StaticResource MouseLeave}" x:Name="MouseLeave_BeginStoryboard"/>
</EventTrigger>
</UserControl.Triggers>
<Grid x:Name="LayoutRoot" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Grid.RenderTransform>
<Ellipse Name="Ellipse" >
<Ellipse.Fill>
<RadialGradientBrush GradientOrigin="0.258,0.21">
<GradientStop x:Name="OuterColor" Offset="0.9"/>
<GradientStop x:Name="InnerColor" Offset="0.312"/>
<GradientStop Color="#FFFFFFFF" Offset="0"/>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>