Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Monday, 23 June 2014

From Task to Rx to Streaming data

Here is a simple example of a ViewModel calling a LoadCustomers service:

public async Task LoadCustomers()
{
IsLoading = true;
Customers.Clear();
var customers = await services.GetAllCustomers();
Customers.AddRange(customers);
IsLoading = false;
}
Note: I’m using the PRISM extension method that allows for adding a range to an observable collection, giving less notifications.  The error handling has been removed to focus on the code.

Here’s the equivalent for Rx:
public async Task LoadCustomers()
{
IsLoading = true;
Customers.Clear();
services.GetAllCustomers().ToObservable()
.SubscribeOn(NewThreadScheduler.Default)
.ObserveOnDispatcher()
.Subscribe(
customers => Customers.AddRange(customers),
() => IsLoading = false);
}

The SubscribeOn extension method is ensuring the GetAllCustomers call is being made on a separate thread to keep the UI as free as possible.  Once the response comes back, the ObserveOnDispatcher ensures the UI thread runs our Customers.AddRange code along with the IsLoading = false code which is running on the Observable OnCompleted event.

So any benefits from this?  Not really.  But imagine our GetAllCustomers wasn’t just a call to a web endpoint.

First we’ll remove the ToObservable() extension method and code up the observable ourselves so we understand what’s actually going on under the hood:

public async Task LoadCustomers()
{
IsLoading = true;
Customers.Clear();

var source = Observable.Create<IEnumerable<Customer>>(
async o =>
{
var response = await services.GetAllCustomers();
o.OnNext(response);
o.OnCompleted();
return Disposable.Empty;
});

source
.SubscribeOn(NewThreadScheduler.Default)
.ObserveOnDispatcher()
.Subscribe(
customers => Customers.AddRange(customers),
() => IsLoading = false);
}

Now if we start to require more work being done to retrieve data than just a web call, like perhaps converting DTOs to UI models, this can be done within the observable code.  Remember this work is not being done on the UI thread so our app is nice and responsive.

Now imagine our services returned observables rather than DTOs or UI models:

public void LoadCustomers()
{
services.GetAllCustomers()
.SubscribeOn(NewThreadScheduler.Default)
.ObserveOnDispatcher()
.Subscribe(customers => Customers.AddRange(customers));
}

We now have a viewmodel that is dealing with observables and doesn’t care whether that data is coming from a web service call, file I/O or a Nirvana (Universal) endpoint that is streaming data.

Friday, 13 September 2013

Setting format for Telerik RadDatePicker

First up remember there are two date pickers the RadDatePicker and the RadDateTimePicker.

You can specialise with your date hardcoded, or have a property that lets the developer set the value:

public class RadDatePickerWithSwissDates : RadDatePicker
{
public RadDatePickerWithSwissDates()
{
var ci = new CultureInfo("")
{
DateTimeFormat = { ShortDatePattern = "dd.MM.yyyy" }
};

this.Culture = ci;
}
}

Or you can use this approach:

public class TelerikDateFormatWorkaround
{
public CultureInfo CultureWithSwissFormat
{
//Hack to get around the fact that there is no custom date format in the Telerik DatePicker
//http://www.telerik.com/community/forums/wpf/datepicker/changing-dateformat.aspx
get
{
var tempCultureInfo = (CultureInfo)CultureInfo.CurrentCulture.Clone();
tempCultureInfo.DateTimeFormat.ShortDatePattern = "dd.MM.yyyy";
return tempCultureInfo;
}
}
}

// add it to the usercontrol resources in the usual way and then...

<Style TargetType="telerik1:RadDatePicker">
<Setter Property="Culture" Value="{Binding Source={StaticResource TelerikDateFormatWorkaround}, Path=CultureWithSwissFormat}"/>
</Style>

BooleanToVisibilityConverterMarkupExtension

public class BooleanToVisibilityConverterMarkupExtension : MarkupExtension, IValueConverter
{
private static BooleanToVisibilityConverterMarkupExtension converter;

public override object ProvideValue(IServiceProvider serviceProvider)
{
return converter ?? (converter = new BooleanToVisibilityConverterMarkupExtension());
}

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var v = (bool?)value;
return v.HasValue && v.Value ? Visibility.Visible : Visibility.Collapsed;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var v = (Visibility)value;
return v == Visibility.Visible;
}
}

<!-- usage in xaml -->
Visibility="{Binding IsVisible, Converter={converters:BooleanToVisibilityConverterMarkupExtension}}">>

Wednesday, 28 August 2013

How to find absolute position of control

The following code from MSDN come in very handy today, just change “this” to your control and it’ll give your the absolute position of your control on the page:

GeneralTransform gt = this.TransformToVisual(Application.Current.RootVisual as UIElement);
Point offset = gt.Transform(new Point(0, 0));
double controlTop = offset.Y;
double controlLeft = offset.X;

Friday, 29 March 2013

Animated Listbox

This example shows a nice fluid movement for items in a wrapping listbox.

Demo

Click here to open the Silverlight page and resize your browser: 

http://stevenhollidge.com/blog-source-code/animatedlistbox

Source code

SL version:  https://github.com/stevenh77/AnimatedListboxSL

WPF version:  https://github.com/stevenh77/AnimatedListboxWPF

Thursday, 15 November 2012

Changing Colours in the VisualStateManager

<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Duration="0:0:0" Storyboard.TargetName="Border" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="#FF1F6BAD" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>

Because I always forget, here’s one way for changing colour in the VisualStateManager.  In this example the name of the UI element happens to be “Border”.

Saturday, 27 October 2012

ClickOnce deployment

Warning:  There are currently issues with ClickOnce installers running on Windows 8 click here

Within Visual Studio select your WPF Project > Properties > Publish tab

1.Set the installation folder

image

2. Click “Updates…” button and set your “Application Updates” settings then click OK:

image

3. Click the “Options…” button and set your application information:

a) For description enter all the appropriate information

image

b) Click on Deployment and enter a “Deployment web page” and select “Automatically generate….”

image

4. Now we are ready to “Publish”, so click the “Publish Wizard…” button:

a) For the first step we’ll export to our local folder then manually FTP to our web server.

image

b) The next step defaults to the installation folder you entered on the Project properties Publish tab

image

c) If your application runs offline you can accept the defaults:

image

d) We are now ready to Publish, click Finish:

image

Now upload the files from your Publish folder to your web server:

image

Sunday, 23 September 2012

INPC Parent Child Notification

Here is a simple example of a parent listening to change notification from a child and exposing an aggregate value (or “denormalized” value in database terminology).

The Order (parent) exposes the TotalCost, which is a sum of the Cost properties in OrderLines (child).

image

public class Order : InpcBase
{
private readonly ObservableCollection<OrderLine> orderLines;

public Order()
{
orderLines = new ObservableCollection<OrderLine>();
}

public decimal TotalCost
{
get { return orderLines.Sum(ol => ol.Cost); }
}

public void AddOrderLine(OrderLine orderLine)
{
orderLine.PropertyChanged += orderLine_PropertyChanged;
}

private void orderLine_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Cost") OnPropertyChanged("TotalCost");
}
}

public class OrderLine : InpcBase
{
private decimal cost;
public decimal Cost
{
get { return cost; }
set
{
if (cost == value) return;
cost = value;
OnPropertyChanged("Cost");
}
}
}

public abstract class InpcBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler == null) return;
handler(this, new PropertyChangedEventArgs(name));
}
}

Wednesday, 23 May 2012

Reporting Test Tool

This app was developed to regression test Crystal Reports. The data for the reports is taken from two SQL databases, a before and after the upgrade version. Reports are generated from both databases and exported to HTML. The user then clicks on the HTML report template to select what objects they wish to be compared during the testing. SQL profiling technology is used to also show the user the slowest sql statements whilst running the reports.

For a better quality video watch it here:  https://vimeo.com/stevenhollidge/reporting-test-tool

Monday, 14 May 2012

Converting images to paths

Just a quick trick to convert an image into a vector based path in xaml. 

To be able to handle anything more than the most basic image you’ll probably need Expression Design installed.

For an example, I’m going to use the logo for what is probably xaml’s arch enemy…. HTML 5!

Here is our example image:  http://www.w3.org/html/logo/downloads/HTML5_Logo_512.png

The first step is to download Inkscape from the web:  http://inkscape.org/

It’s an open source SVG graphics editor.  When you open your PNG file, select to “embed” the image:

image

Now select the object:

image

And from the menu choose “Path > Trace Bitmap…”:

image

Make sure the “Colors” option is selected and click Ok:

image

This will make a create a Vector Path object on top of your original image (which is a bit weird), so you need to “Edit > Copy” then “File > New” and “Edit > Paste” to create a nice clean vector image.

Now we could just “Save As > Xaml” but unfortunately the Xaml created isn’t that compatible with WPF or Silverlight so we’ve got an extra hoop to jump through.  Give it a go and see how you get on.  If the resultant xaml doesn’t work in Kaxaml for example you’ll need to follow these extra steps.

We need to get the image into Expression Design.

Still within Inkscape for now, “Save As” file type PDF (stay with me on this one) and select texts to paths

image

Now rename your “.pdf” file to “.ai” file type and you can open it in Expression Design:

image

Now finally we can export to Xaml Silverlight 4 / WPF canvas and all is good in the world.

image

Sunday, 29 April 2012

UIMessage for Silverlight

Here is a shameless (and less functional) copy of the great little JavaScript project by Hans Fjällemark and John Papa https://github.com/KnockedUp/toastR.

The UIMessage control also works in WPF.

Demo (please click the submit button)

Other Message Types

errorquestioninfo

How to use UIMessage

<UserControl x:Class="UIMessageDemo_SL5.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:UIMessageDemo_SL5"
Width="400"
Height="150">

<Grid x:Name="LayoutRoot" Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>

<Button x:Name="btnShowMessage"
Grid.Column="0"
Width="80"
Height="50"
Click="btnShowMessage_Click"
Content="Submit" />

<local:UIMessage x:Name="Message"
Grid.Column="1"
MessageType="Success"
Text="Success" />

</Grid>

</UserControl>

How to open UIMessage

using System.Windows;

namespace UIMessageDemo_SL5
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
}

private void btnShowMessage_Click(object sender, RoutedEventArgs e)
{
Message.Show();
}
}
}

UIMessage.xaml

<UserControl x:Class="UIMessageDemo_SL5.UIMessage"
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"
x:Name="UIMessageControl"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<UserControl.Resources>
<SolidColorBrush x:Key="ErrorBrush" Color="#D5BD3630" />
<SolidColorBrush x:Key="InfoBrush" Color="#D759ABC3" />
<SolidColorBrush x:Key="SuccessBrush" Color="#E151A351" />
<SolidColorBrush x:Key="QuestionBrush" Color="#DCF9A938" />
<BitmapImage x:Key="ErrorImage" UriSource="images/error.png" />
<BitmapImage x:Key="InfoImage" UriSource="images/info.png" />
<BitmapImage x:Key="SuccessImage" UriSource="images/success.png" />
<BitmapImage x:Key="QuestionImage" UriSource="images/question.png" />
<Storyboard x:Key="FadeIn">
<DoubleAnimation BeginTime="0"
Duration="00:00:02"
From="0"
Storyboard.TargetName="Display"
Storyboard.TargetProperty="Opacity"
To="1" />
</Storyboard>
<Storyboard x:Key="FadeOut">
<DoubleAnimation BeginTime="00:00:01"
Duration="00:00:02"
From="1"
Storyboard.TargetName="Display"
Storyboard.TargetProperty="Opacity"
To="0" />
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">

<Border x:Name="Display"
Width="150"
Height="70"
Background="Pink"
CornerRadius="5"
Opacity="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Image x:Name="Icon"
Grid.Row="0"
Grid.Column="0"
Width="30"
Height="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform" />
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
Foreground="White"
Text="{Binding Path=Text,
ElementName=UIMessageControl,
UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Border>
</Grid>
</UserControl>


UIMessage.xaml.cs

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;

namespace UIMessageDemo_SL5
{
public enum MessageType
{
NotSet = 0,
Error,
Info,
Success,
Question
}
public partial class UIMessage : UserControl
{
#region Fields

private SolidColorBrush _errorBrush;
private SolidColorBrush _infoBrush;
private SolidColorBrush _successBrush;
private SolidColorBrush _questionBrush;

private BitmapImage _errorImage;
private BitmapImage _infoImage;
private BitmapImage _successImage;
private BitmapImage _questionImage;

private Storyboard _fadeInStoryboard;
private Storyboard _fadeOutStoryboard;

#endregion

#region Constructor

public UIMessage()
{
InitializeComponent();
CheckResourcesAreAvailable();

_fadeInStoryboard.Completed += (sender, args) => _fadeOutStoryboard.Begin();
}

#endregion

#region Dependency Properties: MessageType, Text

public static readonly DependencyProperty TypeProperty =
DependencyProperty.Register("MessageType",
typeof(MessageType),
typeof(UIMessage),
new PropertyMetadata(MessageType.NotSet, TypePropertyChanged));

private static void TypePropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var uiMessage = (UIMessage)dependencyObject;
uiMessage.Display.SetValue(Border.BackgroundProperty, uiMessage.GetBrush(uiMessage.MessageType));
uiMessage.Icon.SetValue(Image.SourceProperty, uiMessage.GetImage(uiMessage.MessageType));
}

public MessageType MessageType
{
get { return (MessageType)GetValue(TypeProperty); }
set { SetValue(TypeProperty, value); }
}

public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text",
typeof(string),
typeof(UIMessage),
new PropertyMetadata(default(string)));

public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}

#endregion

#region Methods

private void CheckResourcesAreAvailable()
{
_errorBrush = (SolidColorBrush)this.Resources["ErrorBrush"];
_infoBrush = (SolidColorBrush)this.Resources["InfoBrush"];
_successBrush = (SolidColorBrush)this.Resources["SuccessBrush"];
_questionBrush = (SolidColorBrush)this.Resources["QuestionBrush"];
_errorImage = (BitmapImage)this.Resources["ErrorImage"];
_infoImage = (BitmapImage)this.Resources["InfoImage"];
_successImage = (BitmapImage)this.Resources["SuccessImage"];
_questionImage = (BitmapImage)this.Resources["QuestionImage"];
_fadeInStoryboard = (Storyboard)this.Resources["FadeIn"];
_fadeOutStoryboard = (Storyboard)this.Resources["FadeOut"];

if (_errorBrush == null) throw new Exception("Missing ErrorBrush resource");
if (_infoBrush == null) throw new Exception("Missing InfoBrush resource");
if (_successBrush == null) throw new Exception("Missing SuccessBrush resource");
if (_questionBrush == null) throw new Exception("Missing QuestionBrush resource");
if (_errorImage == null) throw new Exception("Missing BitmapImage ErrorImage resource");
if (_infoImage == null) throw new Exception("Missing BitmapImage InfoImage resource");
if (_successImage == null) throw new Exception("Missing BitmapImage SuccessImage resource");
if (_questionImage == null) throw new Exception("Missing BitmapImage QuestionImage resource");
if (_fadeInStoryboard == null) throw new Exception("Missing Storyboard FadeIn resource");
if (_fadeOutStoryboard == null) throw new Exception("Missing Storyboard FadeOut resource");
}

private SolidColorBrush GetBrush(MessageType type)
{
SolidColorBrush brush = null;
switch (type)
{
case MessageType.Info:
brush = _infoBrush;
break;
case MessageType.Error:
brush = _errorBrush;
break;
case MessageType.Success:
brush = _successBrush;
break;
case MessageType.Question:
brush = _questionBrush;
break;
}
return brush;
}

private BitmapImage GetImage(MessageType type)
{
BitmapImage image = null;
switch (type)
{
case MessageType.Info:
image = _infoImage;
break;
case MessageType.Error:
image = _errorImage;
break;
case MessageType.Success:
image = _successImage;
break;
case MessageType.Question:
image = _questionImage;
break;
}
return image;
}

public void Show()
{
_fadeInStoryboard.Begin();
}

#endregion
}
}

Source

http://stevenhollidge.com/blog-source-code/UIMessageDemo_SL5.zip

http://stevenhollidge.com/blog-source-code/UIMessageDemo_WPF.zip

Wednesday, 25 April 2012

Binding Converter Parameters to StaticResources

Here is the bad news, you can’t but here’s the good news, using a bit of jiggery pokery you can easily work around it!

Scenario

image

I had a view containing three ellipses that I wanted to colour based on a property for their data context.  The expected result was blue if the value was zero, red if the value was greater than zero and yellow if something went wrong.

The Obvious Approach Doesn’t Work

I had my colours set in my UserControl.Resources so I would like to have used the following code:

<UserControl.Resources>
<SolidColorBrush x:Name="ZeroBrush" Color="SteelBlue" />
<SolidColorBrush x:Name="OverZeroBrush" Color="Red" />
</UserControl.Resources>

<Ellipse Fill="{Binding Path=Count,
Converter={converters:CountToBrushConverter
ZeroBrush={StaticResource ZeroBrush},
OverZeroBrush={StaticResource OverZeroBrush}}}" />
public class CountToBrushConverter : MarkupExtension, IMultiValueConverter
{
private static CountToBrushConverter _converter;
private readonly SolidColorBrush INCORRECT_USAGE_OF_CONVERTER = new SolidColorBrush(Color.FromArgb(255, 255, 255, 0));

public SolidColorBrush ZeroBrush { get; set; }
public SolidColorBrush OverZeroBrush { get; set; }

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
int count;
if (!Int32.TryParse(values[0].ToString(), out count)) return INCORRECT_USAGE_OF_CONVERTER;

return count == 0 ? ZeroBrush : OverZeroBrush;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return _converter ?? (_converter = new CountToBrushConverter());
}
}

The problem with this approach is that the value converter properties are not dependency objects and therefore cannot have a binding assigned to them.


The Solution


Swap your IValueConverter for an IMultiValueConverter and use an implementation of the multi-binding approach from WPF. 

<Ellipse Fill="{xaml:MultiBinding Converter={converters:CountToBrushConverter}, 
Source1={Binding Path=Count},
Source2={StaticResource ZeroBrush},
Source3={StaticResource OverZeroBrush}}" />
public class CountToBrushConverter : MarkupExtension, IMultiValueConverter
{
private static CountToBrushConverter _converter;
private readonly SolidColorBrush INCORRECT_USAGE_OF_CONVERTER = new SolidColorBrush(Color.FromArgb(255, 255, 255,0));

/// <summary>
/// Returns a SolidBrushColour based on whether the count = 0 or not
/// </summary>
/// <param name="values">Array of objects: value[0] = Count, value[1] = ZeroBrush, value[2] = OverZeroBrush</param>
/// <param name="targetType">Not used.</param>
/// <param name="parameter">Not used.</param>
/// <param name="culture">Not used.</param>
/// <returns>SolidBrushColor</returns>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length != 3) return INCORRECT_USAGE_OF_CONVERTER;

int count;
if (!Int32.TryParse(values[0].ToString(), out count)) return INCORRECT_USAGE_OF_CONVERTER;

var zeroBrush = values[1] as SolidColorBrush;
if (zeroBrush == null) return INCORRECT_USAGE_OF_CONVERTER;

var overZeroBrush = values[2] as SolidColorBrush;
if (overZeroBrush == null) return INCORRECT_USAGE_OF_CONVERTER;

return count == 0
? zeroBrush
: overZeroBrush;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return _converter ?? (_converter = new CountToBrushConverter());
}
}

Multi Bindings for Silverlight


Henrik Jonsson has an implementation on Code Project:
http://www.codeproject.com/Articles/286171/MultiBinding-in-Silverlight-5

Colin Eberhardt has another option on his blog:
http://www.scottlogic.co.uk/blog/colin/2010/05/silverlight-multibinding-solution-for-silverlight-4/

You can download a zip of the version I used:
http://stevenhollidge.com/blog-source-code/MultiBinding.zip

Monday, 23 April 2012

PropertyPathHelper

Ever needed to get the value from a binding in code?   Well here you go.

public static class PropertyPathHelper
{
private static readonly Dummy _dummy = new Dummy();

public static object GetValue(object source, string propertyPath)
{
var binding = new Binding(propertyPath)
{
Mode = BindingMode.OneTime,
Source = source
};
BindingOperations.SetBinding(_dummy, Dummy.ValueProperty, binding);
return _dummy.GetValue(Dummy.ValueProperty);
}

private class Dummy : DependencyObject
{
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value",
typeof (object),
typeof (Dummy),
new PropertyMetadata(null));
}
}
Thanks to Thomas Levesque for his answer on Stack Overflow:
http://stackoverflow.com/questions/3577802/wpf-getting-a-property-value-from-a-binding-path

BoolToValueConverter<T>

Here is a great little generic BoolTo… converter.  In the example below I use it to define the visibility of a textblock.

using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;

namespace SilverlightGlimpse.Converters
{
public class BoolToVisibilityConverter : BoolToValueConverter<Visibility> { }

public class BoolToValueConverter<T> : MarkupExtension, IValueConverter
{
public T FalseValue { get; set; }
public T TrueValue { get; set; }

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null) return FalseValue;
return (bool)value ? TrueValue : FalseValue;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null && value.Equals(TrueValue);
}

public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
<TextBlock Visibility="{Binding Path=IsInDebugMode, 
Converter={local:BoolToVisibilityConverter
FalseValue=Collapsed,
TrueValue=Visible}}" />


Original author: http://geekswithblogs.net/codingbloke/archive/2010/05/28/a-generic-boolean-value-converter.aspx

Monday, 9 April 2012

Custom Tooltip and Popup

Like with everything else in WPF you can override the style for tooltips.

Standard Tooltip

image_thumb3

Custom Tooltip

image_thumb1[1]

<Window.Resources>
<Style x:Key="CustomTooltip" TargetType="{x:Type ToolTip}">
<Setter Property="HorizontalOffset" Value="50" />
<Setter Property="VerticalOffset" Value="-50" />
<Setter Property="Background" Value="Beige" />
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="18" />
<Setter Property="FontFamily" Value="Segoe UI" />
</Style>
</Window.Resources>

<!-- the following code lives inside the control you want to tooltip -->
<Grid.ToolTip>
<ToolTip Style="{StaticResource CustomTooltip}">
<TextBlock>Custom tooltip</TextBlock>
</ToolTip>
</Grid.ToolTip>

This custom tooltip rather boringly just features a textblock but you can customise with any fonts and colours and include any combination of UI controls such as images, animations or even video.


Source:  http://stevenhollidge.com/blog-source-code/WrappingListbox-CustomTooltip.zip


Custom Tooltip with Shape (Path)


image_thumb1

<Style x:Key="{x:Type ToolTip}" TargetType="ToolTip">
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="HorizontalOffset" Value="0" />
<Setter Property="VerticalOffset" Value="-75" />
<Setter Property="Background" Value="GhostWhite" />
<Setter Property="Foreground" Value="Gray" />
<Setter Property="FontSize" Value="12" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToolTip">
<Canvas Width="200" Height="100">
<Path x:Name="Container"
Canvas.Left="0"
Canvas.Top="0"
Margin="20"
Data="M 0,40 L15,50 15,80 150,80 150,0 15,0 15,30"
Fill="{TemplateBinding Background}"
Stroke="Black">
<Path.Effect>
<DropShadowEffect BlurRadius="10"
Opacity="0.5"
ShadowDepth="4" />
</Path.Effect>
</Path>
<TextBlock Canvas.Left="50"
Canvas.Top="28"
Width="100"
Height="65"
Text="{TemplateBinding Content}"
TextWrapping="Wrapwithoverflow" />
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Source:  http://stevenhollidge.com/blog-source-code/WrappingListbox-CustomTooltip-WithPath.zip


Popup


image_thumb[1]

<Popup x:Name="PopupInfo"
AllowsTransparency="True"
HorizontalOffset="-10"
IsOpen="{Binding ElementName=backgroundGrid,
Path=IsMouseOver,
Mode=OneWay,
UpdateSourceTrigger=PropertyChanged}"
VerticalOffset="-30"
Placement="Right">

<Canvas Width="200" Height="100">
<Path x:Name="Container"
Canvas.Left="0"
Canvas.Top="0"
Margin="20"
Data="M 0,40 L15,50 15,80 150,80 150,0 15,0 15,30"
Fill="Beige"
Stroke="Black">
<Path.Effect>
<DropShadowEffect BlurRadius="10"
Opacity="0.5"
ShadowDepth="4" />
</Path.Effect>
</Path>
<TextBlock Canvas.Left="50"
Canvas.Top="28"
Width="100"
Height="65"
Text="Popup with text...."
TextWrapping="Wrapwithoverflow" />

</Canvas>
</Popup>

Source: http://stevenhollidge.com/blog-source-code/wpf-popup.zip

Saturday, 7 April 2012

Visual State Manager

Here is a great early example app from Microsoft in 2008 that shows off the Visual State Manager, complete with animated transitions between states.

sunnypart-cloudyimagerainy 

Here’s the source that I’ve updated for WPF4.

The Control

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace WeatherStates
{
[TemplatePart(Name = "Core", Type = typeof(FrameworkElement))]
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Sunny", GroupName = "WeatherStates")]
[TemplateVisualState(Name = "PartlyCloudy", GroupName = "WeatherStates")]
[TemplateVisualState(Name = "Cloudy", GroupName = "WeatherStates")]
[TemplateVisualState(Name = "Rainy", GroupName = "WeatherStates")]
public class WeatherControl : Control
{
public WeatherControl()
{
//Set DefaultStyleKey
DefaultStyleKey = typeof(WeatherControl);
}

private FrameworkElement CorePart
{
get { return corePart; }

set
{
FrameworkElement oldCorePart = corePart;

if (oldCorePart != null)
{
oldCorePart.MouseEnter -= corePart_MouseEnter;
oldCorePart.MouseLeave -= corePart_MouseLeave;
oldCorePart.MouseLeftButtonDown -= corePart_MouseLeftButtonDown;
oldCorePart.MouseLeftButtonUp -= corePart_MouseLeftButtonUp;
}

corePart = value;

if (corePart != null)
{
corePart.MouseEnter += corePart_MouseEnter;
corePart.MouseEnter += corePart_MouseEnter;
corePart.MouseLeave += corePart_MouseLeave;
corePart.MouseLeftButtonDown += corePart_MouseLeftButtonDown;
corePart.MouseLeftButtonUp += corePart_MouseLeftButtonUp;
}
}
}

public override void OnApplyTemplate()
{
base.OnApplyTemplate();

CorePart = (FrameworkElement)GetTemplateChild("Core");

GoToState(false);
}

private void GoToState(bool useTransitions)
{
// Go to states in NormalStates state group
if (isPressed)
{
VisualStateManager.GoToState(this, "Pressed", useTransitions);
}
else if (isMouseOver)
{
VisualStateManager.GoToState(this, "MouseOver", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Normal", useTransitions);
}


// Go to states in WeatherStates state group
if (Condition == Condition.PartlyCloudy)
{
VisualStateManager.GoToState(this, "PartlyCloudy", useTransitions);
}
else if (Condition == Condition.Sunny)
{
VisualStateManager.GoToState(this, "Sunny", useTransitions);
}
else if (Condition == Condition.Cloudy)
{
VisualStateManager.GoToState(this, "Cloudy", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Rainy", useTransitions);
}
}

#region input event handlers

private void corePart_MouseEnter(object sender, MouseEventArgs e)
{
isMouseOver = true;
GoToState(true);
}

private void corePart_MouseLeave(object sender, MouseEventArgs e)
{
isMouseOver = false;
GoToState(true);
}

private void corePart_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
isPressed = true;
GoToState(true);
}

private void corePart_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
isPressed = false;
GoToState(true);
}

#endregion

#region public properties

// Temperature DP

public static readonly DependencyProperty TemperatureProperty = DependencyProperty.Register("Temperature",
typeof(string),
typeof(
WeatherControl),
new PropertyMetadata
(OnTemperaturePropertyChanged));

// Condition DP

public static readonly DependencyProperty ConditionProperty = DependencyProperty.Register("Condition",
typeof(Condition),
typeof(WeatherControl
),
new PropertyMetadata(
OnConditionPropertyChanged));


// ConditionDescription DP

public static readonly DependencyProperty ConditionDescriptionProperty =
DependencyProperty.Register("ConditionDescription", typeof(string), typeof(WeatherControl),
new PropertyMetadata(OnConditionDescriptionPropertyChanged));

public string Temperature
{
get { return (string)GetValue(TemperatureProperty); }
set { SetValue(TemperatureProperty, value); }
}

public Condition Condition
{
get { return (Condition)GetValue(ConditionProperty); }
set { SetValue(ConditionProperty, value); }
}

public string ConditionDescription
{
get { return (string)GetValue(ConditionDescriptionProperty); }
set { SetValue(ConditionDescriptionProperty, value); }
}

#endregion

#region Change Notification Handlers

private static void OnTemperaturePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var weather = d as WeatherControl;
var newValue = (string)e.NewValue;
weather.OnWeatherChange(null);
}

private static void OnConditionDescriptionPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var weather = d as WeatherControl;
var newValue = (string)e.NewValue;
weather.OnWeatherChange(null);
}

private static void OnConditionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var weather = d as WeatherControl;
var newValue = (Condition)e.NewValue;
weather.OnWeatherChange(null);
}

#endregion Change Notification Handlers

#region protected methods

protected virtual void OnWeatherChange(RoutedEventArgs e)
{
GoToState(true);
}

#endregion

#region private

private FrameworkElement corePart;

private bool isMouseOver, isPressed;

#endregion
}
}

The Template

<!--  Built-In Style for WeatherControl  -->
<Style TargetType="WeatherStates:WeatherControl">
<Setter Property="Template">
<Setter.Value>

<!-- ControlTemplate -->
<ControlTemplate TargetType="WeatherStates:WeatherControl">

<!-- Template's Root Visual -->
<Grid x:Name="LayoutRoot">

<!-- Resources -->
<Grid.Resources>
<SolidColorBrush x:Key="RainColor" Color="#FF12BAE4" />

<Storyboard x:Key="Glow" RepeatBehavior="Forever">
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[19].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="217.027385875156,25.8495779319949" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="193.271678188256,5.99269073781626" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="192.700388781111,8.43995886902664" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="217.027385875156,25.8495779319949" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[19].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="214.195554236379,24.1598734485195" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="190.017005638817,6.5232359929917" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="190.017005638817,6.5232359929917" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="214.195554236379,24.1598734485195" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[20].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="193.017,11.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="175.497856571438,8.89000731326221" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="176.017,-3.47687567559504" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="193.017,11.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[21].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="143.456021227293,2.28064399600896" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="130.180564027175,4.1319708409094" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="142.199537787091,34.266932435986" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="143.456021227293,2.28064399600896" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[21].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="133.273483440202,3.53683588442785" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="119.998026240084,5.3881627293283" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="132.017,35.5231243244049" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="133.273483440202,3.53683588442785" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[22].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="116.322438561857,5.62804001463961" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="103.046981361739,7.47936685954" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="115.065955121655,37.6143284546166" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="116.322438561857,5.62804001463961" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[22].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="113.15834715917,9.5799379502316" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="109.139373399254,42.4451006795598" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="109.139373399254,42.4451006795598" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="113.15834715917,9.5799379502316" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[22].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="104.017,14.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="99.9980262400841,47.3881627293282" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="99.9980262400841,47.3881627293282" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="104.017,14.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[23].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="77.6002417396145,28.8075111296135" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="73.5812679796986,61.6726738589417" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="73.5812679796986,61.6726738589417" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="77.6002417396145,28.8075111296135" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[17].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="315.045729803776,25.3219750411442" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="258.860765225674,69.4627712921137" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="282.323853363963,67.9607511297636" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="315.045729803776,25.3219750411442" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[17].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="292.017,17.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="251.017,39.5232359929916" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="274.480088138289,38.0212158306414" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="292.017,17.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[18].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="266.045729803776,14.3219750411442" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="238.360206157591,26.0192006054869" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="261.82329429588,24.5171804431367" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="266.045729803776,14.3219750411442" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[16].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="343.017,60.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="328.017,79.5232359929916" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="326.017,98.5230000000012" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="343.017,60.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[16].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="320.017,38.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="296.017,50.5232359929916" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="294.017,69.523" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="320.017,38.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[17].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="302.251552278419,21.5299630489227" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="277.800555964959,34.0145835862353" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="275.800555964959,53.0143475932437" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="302.251552278419,21.5299630489227" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[15].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="312.017,104.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="322.544690203268,105.756783342081" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="300.017,150.523000022605" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="312.017,104.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[16].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="326.937276319773,66.1565751777258" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="279.297174945034,85.1077945894012" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="325.159324267773,97.0957562808475" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="326.937276319773,66.1565751777258" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[15].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="319.017,86.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="299.017,94.5232359929916" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="316.017,116.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="319.017,86.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[14].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="320.316371432994,142.328878996393" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="304.316371432994,184.329114989386" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="329.187070466506,168.017422569527" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="320.316371432994,142.328878996393" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[14].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="314.017,111.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="298.017,153.523235992993" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="312.017,162.52300001507" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="314.017,111.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[15].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="311.443069535654,98.93568215834" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="295.443069535654,140.935918151333" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="287.017,154.523000007535" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="311.443069535654,98.93568215834" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[12].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="332.830026579832,232.35697353529" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="327.830026579832,236.357209528283" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="321.438569719492,237.414695074582" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="332.830026579832,232.35697353529" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[12].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="335.017,219.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="330.017,223.523235992993" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="323.62554313966,224.580721539292" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="335.017,219.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[13].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="336.935763419904,208.262982514449" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="331.935763419904,212.263218507442" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="325.544306559564,213.320704053741" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="336.935763419904,208.262982514449" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[11].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="265.089624097208,267.150471374951" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="289.089624097208,307.150595699357" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="289.710480443727,305.638262962633" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="265.089624097208,267.150471374951" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[11].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="285.017,236.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="309.017,276.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="295.62554313966,269.580609870705" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="285.017,236.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[12].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="291.757418733976,226.163282652512" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="315.757418733976,266.163406976918" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="303.017,224.523" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="291.757418733976,226.163282652512" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[23].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="112.12898097172,37.1807609844687" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="97.017,58.5231243244049" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="83.6717684519183,19.384842444433" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="112.12898097172,37.1807609844687" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[24].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="52.0657937772402,41.1866997589079" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="65.4748802545407,54.3547742531447" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="52.129648706459,15.2164923731728" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="52.0657937772402,41.1866997589079" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="6.85323961573832,115.415938172951" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="39.017,112.071777804023" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="14.017,131.071777804023" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="6.85323961573832,115.415938172951" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="6.85323961573832,133.867284693334" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="39.017,130.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="14.017,149.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="6.85323961573832,133.867284693334" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="6.85323961573832,140.341295751105" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="39.017,136.997135382177" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="14.017,155.997135382177" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="6.85323961573832,140.341295751105" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="41.017,191.543759858496" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="29.017,191.543884182902" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="19.017,194.543884182902" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="41.017,191.543759858496" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="41.017,214.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="29.017,214.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="19.017,217.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="41.017,214.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[4].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="41.017,236.488317217131" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="29.017,236.488441541537" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="19.017,239.488441541537" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="41.017,236.488317217131" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[4].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="13.017,246.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="-2.50446623202902,260.749226988274" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="56.017,221.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="13.017,246.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[4].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="21.017,271.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="30.112430083172,268.111076232185" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="63.017,254.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="21.017,271.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[5].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="24.313235765972,281.823736768663" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="40.6623269021674,270.492257726884" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="65.2612167546261,265.1030033105" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="24.313235765972,281.823736768663" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[6].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="95.969302550663,279.626637384605" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="68.9693025506632,306.626761709011" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="68.9693025506632,306.626761709011" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="95.969302550663,279.626637384605" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[6].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="106.017,285.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="79.017,312.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="79.017,312.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="106.017,285.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[7].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="117.799463014936,292.437387578731" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="90.7994630149357,319.437511903138" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="90.7994630149357,319.437511903138" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="117.799463014936,292.437387578731" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[8].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="164.75002531811,305.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="127.75002531811,289.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="127.75002531811,289.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="164.75002531811,305.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[8].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="197.017,305.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="160.017,289.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="160.017,289.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="197.017,305.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[9].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="209.661178771677,305.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="172.661178771677,289.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="172.661178771677,289.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="209.661178771677,305.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[7].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="122.634571235598,308.078579799153" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="104.017,315.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="101.017,300.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="122.634571235598,308.078579799153" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[7].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="129.017,319.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="117.017,308.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="114.017,293.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="129.017,319.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[8].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="142.903984439585,344.423941493566" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="142.120545463202,295.005830613451" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="139.120545463202,280.005830613451" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="142.903984439585,344.423941493566" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[5].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="60.8118957727822,259.167632153829" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="59.8118957727822,259.167756478235" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="42.8118957727822,277.167756478235" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="60.8118957727822,259.167632153829" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[5].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="75.017,266.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="74.017,266.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="57.017,284.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="75.017,266.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[6].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="82.6621288422787,270.481628811649" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="81.6621288422787,270.481753136054" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="64.6621288422787,288.481753136054" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="82.6621288422787,270.481628811649" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="56.017,103.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="43.017,77.5231243244049" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="18.017,77.5231243244049" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="56.017,103.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="50.3258680260035,114.655559799549" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="37.3258680260035,88.6556841239544" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="38.017,109.523" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="50.3258680260035,114.655559799549" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[9].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="219.127177261807,300.511191325117" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="220.127177261807,314.511315649523" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="171.017,304.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="219.127177261807,300.511191325117" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[9].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="230.017,292.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="231.017,306.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="204.017,313.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="230.017,292.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[10].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="246.856000203449,280.17081038381" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="247.856000203449,294.170934708216" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="224.164828754196,319.017986711914" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="246.856000203449,280.17081038381" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[20].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="172.424990603953,39.1109504900648" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="173.876659701476,26.7198828131649" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="176.017,-0.476875675595004" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="172.424990603953,39.1109504900648" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[20].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="158.017,31.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="159.468669097523,19.1319323231001" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="158.017,5.523124324405" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="158.017,31.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[21].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="149.077319153348,26.8149281025374" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="150.528988250871,14.4238604256375" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="148.431831708911,8.71818042143482" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="149.077319153348,26.8149281025374" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[23].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="62.017,40.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="75.3622315480817,55.6614062043768" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="62.017,16.5231243244049" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="62.017,40.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[24].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="11.017,49.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="58.4007476089011,54.8551469694999" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="36.017,5.52287567559508" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="11.017,49.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[24].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="45.017,80.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="48.2421669872349,54.8551469694999" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="25.017,35.523" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="45.017,80.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="40.017,91.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="16.4472518472481,86.0563295594422" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="39.017,87.5231243244049" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="40.017,91.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="19.017,104.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="20.5202930021668,99.3352854362725" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="31.017,102.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="19.017,104.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="1.05260359587804,115.643816821599" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="26.7159597348007,119.534439346329" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="9.58585169555629,142.706527395238" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="1.05260359587804,115.643816821599" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[10].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="251.493000956816,292.274982366367" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="235.030807105945,268.835780408701" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="203.493000956816,293.275106690773" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="251.493000956816,292.274982366367" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[10].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="275.017,286.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="258.554806149129,263.083798042334" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="227.017,287.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="275.017,286.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[11].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="300.955645580896,280.180599130366" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="284.493451730025,256.7413971727" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="252.955645580896,281.180723454773" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="300.955645580896,280.180599130366" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="45.3893843464702,162.487855077983" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="32.4754423162679,161.16156342645" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="42.3893843464702,166.487979402389" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="45.3893843464702,162.487855077983" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="30.017,177.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="17.1030579697977,176.196708348467" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="27.017,181.523124324406" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="30.017,177.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="14.7279805742795,192.476608861205" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="1.81403854407725,191.150317209672" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="11.7279805742795,196.476733185611" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="14.7279805742795,192.476608861205" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[13].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="297.722923926225,169.892684367878" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="323.595997007497,199.389483896091" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="329.722923926225,202.892684367878" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="297.722923926225,169.892684367878" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[13].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="301.017,164.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="326.890073081272,194.019799528213" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="333.017,197.523" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="301.017,164.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[14].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="314.807335940773,142.043327499874" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="340.680409022045,171.540127028087" />
<SplinePointKeyFrame KeyTime="00:00:00.6" Value="346.807335940773,175.043327499874" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="314.807335940773,142.043327499874" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[18].(BezierSegment.Point2)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="253.326079868027,32.7915428281289" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="229.384485286995,24.130104946938" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="253.326079868027,32.7915428281289" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[18].(BezierSegment.Point3)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="244.017,35.523" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="220.075405418968,26.8615621188091" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="244.017,35.523" />
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[19].(BezierSegment.Point1)">
<SplinePointKeyFrame KeyTime="00:00:00" Value="236.944780968799,37.5981205992084" />
<SplinePointKeyFrame KeyTime="00:00:00.3" Value="213.003186387767,28.9366827180175" />
<SplinePointKeyFrame KeyTime="00:00:00.9" Value="236.944780968799,37.5981205992084" />
</PointAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00.000000" Value="1.048" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="1.048" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="1.1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00.000000" Value="1.048" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="1.048" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="1.1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.068" />
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.025" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="1.068" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.966" />
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.986" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="0.966" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.039" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1.08" />
<SplineDoubleKeyFrame KeyTime="00:00:00.7000000" Value="1.032" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="1.039" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.118" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1.134" />
<SplineDoubleKeyFrame KeyTime="00:00:00.7000000" Value="1.117" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="1.118" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain1"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-20" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain2"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="-10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9" Value="10" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain3"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-15" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain4"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="10" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain5"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="20" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain6"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="-30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="40" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="5" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain7"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="35" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-15" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain8"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="-10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-5" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain9"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="5" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain10"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-20" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain11"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="8" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-10" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain12"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="15" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain13"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-25" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-15" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain14"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="5" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain15"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="-5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="20" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain16"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="-5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-20" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain17"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-30" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="-30" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain18"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="10" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="15" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rain19"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[1].(SkewTransform.AngleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="-5" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="20" />
<SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="-15" />
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="20" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>

<Storyboard x:Key="Burn" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Offset)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.719" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4" Value="0.772" />
<SplineDoubleKeyFrame KeyTime="00:00:00.8" Value="0.719" />
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Duration="00:00:00"
Storyboard.TargetName="Rays"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[2].(GradientStop.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFEE9015" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFF1A11D" />
<SplineColorKeyFrame KeyTime="00:00:00.4000000" Value="#FFFBB238" />
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="#FFF1A11D" />
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Rays" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[3].(GradientStop.Offset)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.737" />
<SplineDoubleKeyFrame KeyTime="00:00:00.4000000" Value="0.911" />
<SplineDoubleKeyFrame KeyTime="00:00:00.8" Value="0.737" />
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFCBDBF9" />
<SplineColorKeyFrame KeyTime="00:00:00.4000000" Value="#FFA2BEF2" />
<SplineColorKeyFrame KeyTime="00:00:00.8000000" Value="#FFCBDBF9" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFB3CCFB" />
<SplineColorKeyFrame KeyTime="00:00:00.2000000" Value="#FFCBDBF9" />
<SplineColorKeyFrame KeyTime="00:00:00.6000000" Value="#FFA2BEF2" />
<SplineColorKeyFrame KeyTime="00:00:00.8000000" Value="#FFB3CCFB" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFB4CBF7" />
<SplineColorKeyFrame KeyTime="00:00:00.2000000" Value="#FFA2BEF2" />
<SplineColorKeyFrame KeyTime="00:00:00.6000000" Value="#FFCBDBF9" />
<SplineColorKeyFrame KeyTime="00:00:00.8000000" Value="#FFB4CBF7" />
</ColorAnimationUsingKeyFrames>
</Storyboard>

<Storyboard x:Key="PartlyCloudyStoryboard">
<DoubleAnimation Duration="0"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
</Storyboard>

<Storyboard x:Key="CloudyStoryboard">
<DoubleAnimation Duration="0"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="Rays"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="0" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="Core"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="0" />
</Storyboard>

<Storyboard x:Key="RainyStoryboard">
<DoubleAnimation Duration="0"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="RainCanvas"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="1" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="Rays"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="0" />
<DoubleAnimation Duration="0"
Storyboard.TargetName="Core"
Storyboard.TargetProperty="(UIElement.Opacity)"
To="0" />
</Storyboard>
</Grid.Resources>


<!-- VisualStateManager -->
<VisualStateManager.VisualStateGroups>

<!-- CommonStates StateGroup -->
<VisualStateGroup x:Name="CommonStates">

<!-- CommonStates States -->
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver" Storyboard="{StaticResource Glow}" />
<VisualState x:Name="Pressed" Storyboard="{StaticResource Burn}" />

<!-- CommonStates Transitions -->
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:1" />
<VisualTransition GeneratedDuration="0:0:.4" To="Pressed" />
<VisualTransition From="Pressed" GeneratedDuration="0:0:.4" />
</VisualStateGroup.Transitions>
</VisualStateGroup>

<!-- WeatherStates StateGroup -->
<VisualStateGroup x:Name="WeatherStates">

<!-- WeatherStates States -->
<VisualState x:Name="Sunny" />
<VisualState x:Name="PartlyCloudy" Storyboard="{StaticResource PartlyCloudyStoryboard}" />
<VisualState x:Name="Cloudy" Storyboard="{StaticResource CloudyStoryboard}" />
<VisualState x:Name="Rainy" Storyboard="{StaticResource RainyStoryboard}" />


<!-- WeatherStates Transitions -->
<VisualStateGroup.Transitions>

<!-- Sunny to PartlyCloudy Transition -->
<VisualTransition From="Sunny" To="PartlyCloudy">
<Storyboard Duration="0:0:.5">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-150" />
<SplineDoubleKeyFrame KeySpline="0.173,0.019,1,0.484"
KeyTime="00:00:00.5000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeySpline="0.173,0.019,1,1"
KeyTime="00:00:00.2000000"
Value="0.1" />
<SplineDoubleKeyFrame KeySpline="0,0,1,0.484"
KeyTime="00:00:00.5000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>

<!-- Sunny to Cloudy Transition -->
<VisualTransition From="Sunny" To="Cloudy">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-310.971" />
<SplineDoubleKeyFrame KeySpline="0.685,0.069,1,1"
KeyTime="00:00:00.5000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-310.971" />
<SplineDoubleKeyFrame KeySpline="0.701,0.229,0.965,0.629"
KeyTime="00:00:00.5000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-310.971" />
<SplineDoubleKeyFrame KeySpline="0.917,0,0.921,0.629"
KeyTime="00:00:00.5000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="BottomCloud"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeySpline="0.685,0.069,1,1"
KeyTime="00:00:00.2000000"
Value="0.1" />
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeySpline="0.701,0.229,1,1"
KeyTime="00:00:00.2000000"
Value="0.1" />
<SplineDoubleKeyFrame KeySpline="0,0,0.965,0.629"
KeyTime="00:00:00.5000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeySpline="0.917,0,1,1"
KeyTime="00:00:00.2000000"
Value="0.1" />
<SplineDoubleKeyFrame KeySpline="0,0,0.921,0.629"
KeyTime="00:00:00.5000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rays"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1" />
<SplineDoubleKeyFrame KeySpline="0,0,1,0.484"
KeyTime="00:00:00.6000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Core"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1" />
<SplineDoubleKeyFrame KeySpline="0,0,1,0.484"
KeyTime="00:00:00.6000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>

<!-- PartlyCloudy to Cloudy Transition -->
<VisualTransition From="PartlyCloudy" To="Cloudy">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-310.971" />
<SplineDoubleKeyFrame KeySpline="0.701,0.229,0.965,0.629"
KeyTime="00:00:00.5000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="-310.971" />
<SplineDoubleKeyFrame KeySpline="0.917,0,0.921,0.629"
KeyTime="00:00:00.5000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="MiddleCloud"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeySpline="0.701,0.229,1,1"
KeyTime="00:00:00.2000000"
Value="0.1" />
<SplineDoubleKeyFrame KeySpline="0,0,0.965,0.629"
KeyTime="00:00:00.5000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="TopCloud"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
<SplineDoubleKeyFrame KeySpline="0.917,0,1,1"
KeyTime="00:00:00.2000000"
Value="0.1" />
<SplineDoubleKeyFrame KeySpline="0,0,0.921,0.629"
KeyTime="00:00:00.5000000"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Rays"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1" />
<SplineDoubleKeyFrame KeySpline="0,0,1,0.484"
KeyTime="00:00:00.6000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00"
Storyboard.TargetName="Core"
Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1" />
<SplineDoubleKeyFrame KeySpline="0,0,1,0.484"
KeyTime="00:00:00.6000000"
Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>

<VisualTransition GeneratedDuration="0:0:0.3" />
</VisualStateGroup.Transitions>
</VisualStateGroup>

</VisualStateManager.VisualStateGroups>

<Canvas>
<!-- Rays -->
<Path x:Name="Rays"
Canvas.Left="62.983"
Canvas.Top="-3.523"
Stretch="None"
Stroke="{x:Null}">
<Path.Data>
<PathGeometry>
<PathFigure StartPoint="28.0174541641301,61.2980742923269">
<BezierSegment Point1="22.3263221901336,72.4306340918764"
Point2="16.4472518472481,86.0563295594422"
Point3="20.5202930021668,99.3352854362725" />
<BezierSegment Point1="26.7159597348007,119.534439346329"
Point2="6.85323961573832,115.415938172951"
Point3="6.85323961573832,133.867284693334" />
<BezierSegment Point1="6.85323961573832,140.341295751105"
Point2="32.4754423162679,161.16156342645"
Point3="17.1030579697977,176.196708348467" />
<BezierSegment Point1="1.81403854407725,191.150317209672"
Point2="0.01966987269995,204.458602862985"
Point3="0.01966987269995,227.437843004489" />
<BezierSegment Point1="0.01966987269995,249.40316022162"
Point2="-1.8463132732129,241.240787819656"
Point3="30.7705830419881,248.602637063567" />
<BezierSegment Point1="41.3204798609835,250.983818558266"
Point2="31.3714533167345,278.007139394266"
Point3="45.5765575439523,285.362507240437" />
<BezierSegment Point1="53.221686386231,289.321136052086"
Point2="75.3906659456177,266.098988785635"
Point3="85.4383633949545,271.99535140103" />
<BezierSegment Point1="97.2208264098902,278.909738979761"
Point2="113.487632821565,288.157929788435"
Point3="119.870061585967,299.602349989282" />
<BezierSegment Point1="133.757046025552,324.503291482848"
Point2="130.61845776224,310.983022818256"
Point3="162.88543244413,310.983022818256" />
<BezierSegment Point1="175.529611215807,310.983022818256"
Point2="199.830296558437,321.199085063184"
Point3="210.72011929663,313.210893738067" />
<BezierSegment Point1="227.559119500079,300.858704121877"
Point2="235.030807105945,268.835780408701"
Point3="258.554806149129,263.083798042334" />
<BezierSegment Point1="284.493451730025,256.7413971727"
Point2="287.601038214373,277.002237518707"
Point3="307.528414117165,246.374766143756" />
<BezierSegment Point1="314.268832851141,236.015048796268"
Point2="307.619282928068,216.87919220265"
Point3="309.806256348236,204.04521866736" />
<BezierSegment Point1="311.72501976814,192.785201181809"
Point2="323.595997007497,199.389483896091"
Point3="326.890073081272,194.019799528213" />
<BezierSegment Point1="340.680409022045,171.540127028087"
Point2="336.606048858268,147.963981503399"
Point3="330.306677425274,117.158102507006" />
<BezierSegment Point1="327.732746960928,104.570784665346"
Point2="320.989920320051,75.7440646248508"
Point3="306.489309796732,79.2896886439032" />
<BezierSegment Point1="285.262376978775,84.4800027157924"
Point2="280.321724356253,103.927229621517"
Point3="273.488202342187,69.3952344326231" />
<BezierSegment Point1="268.71582583232,45.278873595694"
Point2="260.832035421898,53.6635602579779"
Point3="252.988270196224,23.7240249588558" />
<BezierSegment Point1="240.331476353815,10.2199895713512"
Point2="229.384485286995,24.130104946938"
Point3="220.075405418968,26.8615621188091" />
<BezierSegment Point1="213.003186387767,28.9366827180175"
Point2="186.884060518798,25.2166628313712"
Point3="183.62938796936,25.7472080865466" />
<BezierSegment Point1="169.110238901981,28.1139794068171"
Point2="173.876659701476,26.7198828131649"
Point3="159.468669097523,19.1319323231001" />
<BezierSegment Point1="150.528988250871,14.4238604256375"
Point2="143.456021227293,2.28064399600896"
Point3="133.273483440202,3.53683588442785" />
<BezierSegment Point1="116.322438561857,5.62804001463961"
Point2="121.156225506503,12.2392460986345"
Point3="112.014878347333,17.1823081484029" />
<BezierSegment Point1="85.5981200869475,31.4668192780164"
Point2="125.474212519802,52.3191671888455"
Point3="75.3622315480817,55.6614062043768" />
<BezierSegment Point1="65.4110253253219,56.3251059632847"
Point2="58.4007476089011,54.8551469694999"
Point3="48.2421669872349,54.8551469694999" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.Fill>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5"
CenterY="0.5"
ScaleX="0.806"
ScaleY="0.806" />
<SkewTransform AngleX="0" AngleY="0" CenterX="0.5" CenterY="0.5" />
<RotateTransform Angle="0" CenterX="0.5" CenterY="0.5" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Offset="0.004" Color="#FFFF8A54" />
<GradientStop Offset="1" Color="#FFFBCF36" />
<GradientStop Offset="0.522" Color="#FFFCAD44" />
<GradientStop Offset="0.522" Color="#FFF1A11D" />
</RadialGradientBrush>
</Path.Fill>
</Path>

<!-- Core PART -->
<Ellipse x:Name="Core"
Canvas.Left="131.5"
Canvas.Top="59"
Width="200"
Height="200"
Stroke="{x:Null}">
<Ellipse.Fill>
<RadialGradientBrush>
<GradientStop Offset="0.004" Color="#FFFFD954" />
<GradientStop Offset="1" Color="#FFE9F515" />
<GradientStop Offset="0.911" Color="#FFF1F712" />
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>

<!-- Bottom Cloud -->
<Path x:Name="BottomCloud"
Canvas.Left="6.87"
Canvas.Top="167.041"
Width="252.308"
Height="170.216"
Data="M290.98194,186.52432 C286.3447,193.55139 280.11695,228.80665 301.59189,232.38581 296.6266,239.0062 288.54087,242.91825 285,250 280.34656,259.30688 268.05813,280.85927 287.52861,293.04937 295.56457,298.08053 336.25528,293.49338 337.75281,286.00574 351.81571,318.20517 360.7299,310.2986 377.9321,310.15575 390.21954,310.05372 411.41423,303.41627 415.09759,284.99951 434.5749,294.73816 460.3604,327.52778 493.55493,306.95823 504.6382,300.0903 496.21589,257.64739 &#10;498.15315,257.00973 520.41337,249.68267 534.42526,268.88598 525.42862,223.90279 522.14427,207.48103 499.88139,198.46355 479.38453,198.46355 482.41125,189.38338 479.2321,166.77665 457.32944,158.51384 455.91432,157.97998 422.49651,156.53304 410,179 403.95004,189.87696 401.00935,142.41531 369.4914,144.46102 343.46931,146.15002 342.50522,172.29956 332.73066,182.07411 328.74698,186.05779 309.31591,158.74185 290.98194,186.52432 z"
Opacity="0"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="#FFACB0B1">
<Path.Fill>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5"
CenterY="0.5"
ScaleX="1.283"
ScaleY="1.322" />
<SkewTransform CenterX="0.5" CenterY="0.5" />
<RotateTransform CenterX="0.5" CenterY="0.5" />
<TranslateTransform X="-0.167" Y="-0.125" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="#FFCBDBF9" />
<GradientStop Offset="0.254" Color="#FEFCFDFE" />
</RadialGradientBrush>
</Path.Fill>
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>

<!-- Middle Cloud -->
<Path x:Name="MiddleCloud"
Canvas.Left="211.87"
Canvas.Top="84.041"
Width="252.308"
Height="170.216"
Data="M290.98194,186.52432 C286.3447,193.55139 280.11695,228.80665 301.59189,232.38581 296.6266,239.0062 288.54087,242.91825 285,250 280.34656,259.30688 268.05813,280.85927 287.52861,293.04937 295.56457,298.08053 336.25528,293.49338 337.75281,286.00574 351.81571,318.20517 360.7299,310.2986 377.9321,310.15575 390.21954,310.05372 411.41423,303.41627 415.09759,284.99951 434.5749,294.73816 460.3604,327.52778 493.55493,306.95823 504.6382,300.0903 496.21589,257.64739&#10;498.15315,257.00973 520.41337,249.68267 534.42526,268.88598 525.42862,223.90279 522.14427,207.48103 499.88139,198.46355 479.38453,198.46355 482.41125,189.38338 479.2321,166.77665 457.32944,158.51384 455.91432,157.97998 422.49651,156.53304 410,179 403.95004,189.87696 401.00935,142.41531 369.4914,144.46102 343.46931,146.15002 342.50522,172.29956 332.73066,182.07411 328.74698,186.05779 309.31591,158.74185 290.98194,186.52432 z"
IsHitTestVisible="False"
Opacity="0"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="#FFACB0B1">
<Path.Fill>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5"
CenterY="0.5"
ScaleX="1.283"
ScaleY="1.322" />
<SkewTransform CenterX="0.5" CenterY="0.5" />
<RotateTransform CenterX="0.5" CenterY="0.5" />
<TranslateTransform X="-0.167" Y="-0.125" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="#FFCBDBF9" />
<GradientStop Offset="0.254" Color="#FEFCFDFE" />
</RadialGradientBrush>
</Path.Fill>
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>

<!-- Top Cloud -->
<Path x:Name="TopCloud"
Canvas.Left="47.87"
Canvas.Top="41.041"
Width="252.308"
Height="170.216"
Data="M290.98194,186.52432 C286.3447,193.55139 280.11695,228.80665 301.59189,232.38581 296.6266,239.0062 288.54087,242.91825 285,250 280.34656,259.30688 268.05813,280.85927 287.52861,293.04937 295.56457,298.08053 336.25528,293.49338 337.75281,286.00574 351.81571,318.20517 360.7299,310.2986 377.9321,310.15575 390.21954,310.05372 411.41423,303.41627 415.09759,284.99951 434.5749,294.73816 460.3604,327.52778 493.55493,306.95823 504.6382,300.0903 496.21589,257.64739&#10;498.15315,257.00973 520.41337,249.68267 534.42526,268.88598 525.42862,223.90279 522.14427,207.48103 499.88139,198.46355 479.38453,198.46355 482.41125,189.38338 479.2321,166.77665 457.32944,158.51384 455.91432,157.97998 422.49651,156.53304 410,179 403.95004,189.87696 401.00935,142.41531 369.4914,144.46102 343.46931,146.15002 342.50522,172.29956 332.73066,182.07411 328.74698,186.05779 309.31591,158.74185 290.98194,186.52432 z"
IsHitTestVisible="False"
Opacity="0"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="#FFACB0B1">
<Path.Fill>
<RadialGradientBrush>
<RadialGradientBrush.RelativeTransform>
<TransformGroup>
<ScaleTransform CenterX="0.5"
CenterY="0.5"
ScaleX="1.283"
ScaleY="1.322" />
<SkewTransform CenterX="0.5" CenterY="0.5" />
<RotateTransform CenterX="0.5" CenterY="0.5" />
<TranslateTransform X="-0.167" Y="-0.125" />
</TransformGroup>
</RadialGradientBrush.RelativeTransform>
<GradientStop Color="#FFFFFFFF" />
<GradientStop Offset="1" Color="#FFCBDBF9" />
<GradientStop Offset="0.254" Color="#FEFCFDFE" />
</RadialGradientBrush>
</Path.Fill>
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="-0.686" />
<TranslateTransform X="0.029422772005858633" Y="-0.0073342317098052945" />
</TransformGroup>
</Path.RenderTransform>
</Path>

<!-- RainCanvas -->
<Canvas x:Name="RainCanvas" Opacity="0">
<!-- Rain -->
<Path x:Name="Rain1"
Canvas.Left="62"
Canvas.Top="203"
Width="5"
Height="34"
Data="M65,205 L64,235"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>

<Path x:Name="Rain2"
Canvas.Left="102"
Canvas.Top="226"
Width="4"
Height="46"
Data="M104,228 L104,270"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>

<Path x:Name="Rain3"
Canvas.Left="140"
Canvas.Top="228"
Width="4"
Height="23"
Data="M142,230 L142,249"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain4"
Canvas.Left="200"
Canvas.Top="265"
Width="7"
Height="56"
Data="M202,267 L205,319"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain5"
Canvas.Left="169"
Canvas.Top="210"
Width="5"
Height="28"
Data="M172,212 L171,236"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>

</Path>
<Path x:Name="Rain6"
Canvas.Left="157"
Canvas.Top="273"
Width="5"
Height="26"
Data="M160,275 L159,297"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain7"
Canvas.Left="246"
Canvas.Top="252"
Width="4"
Height="25"
Data="M248,254 L248,275"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain8"
Canvas.Left="335"
Canvas.Top="263"
Width="4"
Height="31"
Data="M337,265 L337,292"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain9"
Canvas.Left="372"
Canvas.Top="272"
Width="5"
Height="31"
Data="M374,274 L375,301"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain10"
Canvas.Left="428"
Canvas.Top="268"
Width="5"
Height="25"
Data="M431,270 L430,291"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain11"
Canvas.Left="296"
Canvas.Top="263"
Width="5"
Height="35"
Data="M299,265 L298,296"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain12"
Canvas.Left="264"
Canvas.Top="278"
Width="5"
Height="37"
Data="M267,280 L266,313"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain13"
Canvas.Left="234"
Canvas.Top="295"
Width="4"
Height="31"
Data="M236,297 L236,324"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain14"
Canvas.Left="318"
Canvas.Top="308"
Width="4"
Height="40"
Data="M320,310 L320,346"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain15"
Canvas.Left="403"
Canvas.Top="310"
Width="9"
Height="26"
Data="M410,312 L405,334"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain16"
Canvas.Left="109"
Canvas.Top="289"
Width="4"
Height="26"
Data="M111,291 L111,313"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain17"
Canvas.Left="66"
Canvas.Top="256"
Width="4"
Height="22"
Data="M68,258 L68,276"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain18"
Canvas.Left="141"
Canvas.Top="315"
Width="5"
Height="28"
Data="M143,317 L144,341"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="Rain19"
Canvas.Left="87"
Canvas.Top="295"
Width="6"
Height="45"
Data="M89,297 L91,338"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="{StaticResource RainColor}"
StrokeThickness="4">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0" />
<RotateTransform Angle="0" />
<TranslateTransform X="0" Y="0" />
</TransformGroup>
</Path.RenderTransform>
</Path>

</Canvas>
<!-- /RainCanvas -->

</Canvas>


<!-- Temperature -->
<StackPanel Width="200"
HorizontalAlignment="Right"
VerticalAlignment="Bottom">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding Temperature}" />
<TextBlock Text=" degrees" />
</StackPanel>

<TextBlock Text="{TemplateBinding ConditionDescription}" TextWrapping="Wrap" />

</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>

</Setter>

</Style>


Source (updated for WPF4): http://stevenhollidge.com/blog-source-code/WeatherStates.zip


Original page: http://windowsclient.net/wpf/wpf35/wpf-35sp1-toolkit-visual-state-manager-overview.aspx