XAML / WPF simple colour animation - wpf

I am trying to replicate this colour animation based on the MouseEnter/MouseLeave trigger - https://www.youtube.com/watch?v=4kih1BSRYxY
I created a Storyboard using Blend, however I couldn't find the best (correct!) control/effect to use, so I created it using multi-Canvas within a grid. As you can see it's nowhere near as smooth as the video. What am I doing wrong? Should I tweak the timings, or is there another control I should be using? Can I use the expander for this type of thing?
I want to achieve this using pure XAML, no code behind.
<Window x:Class="ColourAnimation.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="MenuAnimation">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas">
<EasingColorKeyFrame KeyTime="0:0:0.0" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas1">
<EasingColorKeyFrame KeyTime="0:0:0.1" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas2">
<EasingColorKeyFrame KeyTime="0:0:0.1" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas3">
<EasingColorKeyFrame KeyTime="0:0:0.2" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas4">
<EasingColorKeyFrame KeyTime="0:0:0.2" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas5">
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas6">
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas7">
<EasingColorKeyFrame KeyTime="0:0:0.4" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas8">
<EasingColorKeyFrame KeyTime="0:0:0.4" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas9">
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas10">
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas11">
<EasingColorKeyFrame KeyTime="0:0:0.6" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas12">
<EasingColorKeyFrame KeyTime="0:0:0.6" Value="Red"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MenuAnimation2">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas13">
<EasingColorKeyFrame KeyTime="0:0:0.0" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas14">
<EasingColorKeyFrame KeyTime="0:0:0.1" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas15">
<EasingColorKeyFrame KeyTime="0:0:0.1" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas16">
<EasingColorKeyFrame KeyTime="0:0:0.2" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas17">
<EasingColorKeyFrame KeyTime="0:0:0.2" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas18">
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas19">
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas20">
<EasingColorKeyFrame KeyTime="0:0:0.4" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas21">
<EasingColorKeyFrame KeyTime="0:0:0.4" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas22">
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas23">
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas24">
<EasingColorKeyFrame KeyTime="0:0:0.6" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas25">
<EasingColorKeyFrame KeyTime="0:0:0.6" Value="Green"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MenuAnimationReversed">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas">
<SplineColorKeyFrame KeyTime="0:0:0.0" Value="Red"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas1">
<SplineColorKeyFrame KeyTime="0:0:1.0" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas2">
<SplineColorKeyFrame KeyTime="0:0:1.0" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas3">
<SplineColorKeyFrame KeyTime="0:0:0.8" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas4">
<SplineColorKeyFrame KeyTime="0:0:0.8" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas5">
<SplineColorKeyFrame KeyTime="0:0:0.6" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas6">
<SplineColorKeyFrame KeyTime="0:0:0.6" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas7">
<SplineColorKeyFrame KeyTime="0:0:0.4" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas8">
<SplineColorKeyFrame KeyTime="0:0:0.4" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas9">
<SplineColorKeyFrame KeyTime="0:0:0.2" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas10">
<SplineColorKeyFrame KeyTime="0:0:0.2" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas11">
<SplineColorKeyFrame KeyTime="0:0:0.0" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas12">
<SplineColorKeyFrame KeyTime="0:0:0.0" Value="Red"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MenuAnimationReversed2">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas13">
<SplineColorKeyFrame KeyTime="0:0:0.0" Value="Green"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas14">
<SplineColorKeyFrame KeyTime="0:0:1.0" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas15">
<SplineColorKeyFrame KeyTime="0:0:1.0" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas16">
<SplineColorKeyFrame KeyTime="0:0:0.8" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas17">
<SplineColorKeyFrame KeyTime="0:0:0.8" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas18">
<SplineColorKeyFrame KeyTime="0:0:0.6" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas19">
<SplineColorKeyFrame KeyTime="0:0:0.6" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas20">
<SplineColorKeyFrame KeyTime="0:0:0.4" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas21">
<SplineColorKeyFrame KeyTime="0:0:0.4" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas22">
<SplineColorKeyFrame KeyTime="0:0:0.2" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas23">
<SplineColorKeyFrame KeyTime="0:0:0.2" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas24">
<SplineColorKeyFrame KeyTime="0:0:0.0" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="canvas25">
<SplineColorKeyFrame KeyTime="0:0:0.0" Value="Green"/>
<SplineColorKeyFrame KeyTime="0:0:1" Value="White"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger
SourceName="btnCraig"
RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource MenuAnimation}"/>
</EventTrigger>
<EventTrigger
SourceName="btnCraig"
RoutedEvent="MouseLeave">
<BeginStoryboard Storyboard="{StaticResource MenuAnimationReversed}"/>
</EventTrigger>
<EventTrigger
SourceName="btnCraig2"
RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource MenuAnimation2}"/>
</EventTrigger>
<EventTrigger
SourceName="btnCraig2"
RoutedEvent="MouseLeave">
<BeginStoryboard Storyboard="{StaticResource MenuAnimationReversed2}"/>
</EventTrigger>
</Window.Triggers>
<Grid>
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="26" Margin="10,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas1" HorizontalAlignment="Left" Height="26" Margin="12,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas2" HorizontalAlignment="Left" Height="26" Margin="14,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas3" HorizontalAlignment="Left" Height="26" Margin="16,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas4" HorizontalAlignment="Left" Height="26" Margin="18,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas5" HorizontalAlignment="Left" Height="26" Margin="20,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas6" HorizontalAlignment="Left" Height="26" Margin="22,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas7" HorizontalAlignment="Left" Height="26" Margin="24,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas8" HorizontalAlignment="Left" Height="26" Margin="26,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas9" HorizontalAlignment="Left" Height="26" Margin="28,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas10" HorizontalAlignment="Left" Height="26" Margin="30,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas11" HorizontalAlignment="Left" Height="26" Margin="32,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas12" HorizontalAlignment="Left" Height="26" Margin="34,72,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Button x:Name="btnCraig" Content="Button1" HorizontalAlignment="Left" Margin="53,76,0,0" VerticalAlignment="Top" Width="68" Background="Transparent" BorderBrush="Transparent" BorderThickness="0,0,0,0"/>
<Canvas x:Name="canvas13" HorizontalAlignment="Left" Height="26" Margin="10,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas14" HorizontalAlignment="Left" Height="26" Margin="12,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas15" HorizontalAlignment="Left" Height="26" Margin="14,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas16" HorizontalAlignment="Left" Height="26" Margin="16,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas17" HorizontalAlignment="Left" Height="26" Margin="18,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas18" HorizontalAlignment="Left" Height="26" Margin="20,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas19" HorizontalAlignment="Left" Height="26" Margin="22,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas20" HorizontalAlignment="Left" Height="26" Margin="24,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas21" HorizontalAlignment="Left" Height="26" Margin="26,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas22" HorizontalAlignment="Left" Height="26" Margin="28,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas23" HorizontalAlignment="Left" Height="26" Margin="30,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas24" HorizontalAlignment="Left" Height="26" Margin="32,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Canvas x:Name="canvas25" HorizontalAlignment="Left" Height="26" Margin="34,95,0,0" VerticalAlignment="Top" Width="5" Background="White"/>
<Button x:Name="btnCraig2" Content="Button2" HorizontalAlignment="Left" Margin="53,95,0,0" VerticalAlignment="Top" Width="59" Background="Transparent" BorderBrush="Transparent"/>
</Grid>

Sorry for delay - I thought I posted this earlier.
My mainwindow markup
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="140"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListBox Name="ViewSelect"
ItemsSource="{Binding ViewChoices}"
SelectedItem="{Binding SelectedViewChoice, Mode=TwoWay}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="{Binding Brush}">
<Rectangle.RenderTransform>
<ScaleTransform ScaleX=".1" ScaleY="1"/>
</Rectangle.RenderTransform>
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Binding="{Binding IsMouseOver, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Rectangle.RenderTransform).(ScaleTransform.ScaleX)"
From="0.1" To=".9" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Rectangle.RenderTransform).(ScaleTransform.ScaleX)"
From="0.9" To=".1" Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<Button Content="{Binding Name}"
Grid.Column="1"
Background="Transparent"
Command="{Binding ChoiceCommand}"
BorderThickness="0"
/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Notice that I'm templating data into a listboxitem which has a rectangle and button in it. The buttons do nothing in my code here because I've not set up any commands for them. But they are ready to do so...
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Media;
namespace wpf_AnimatedMenu
{
public class MainWindowViewModel : INotifyPropertyChanged
{
public ObservableCollection<ViewChoice> ViewChoices { get; set; }
= new ObservableCollection<ViewChoice>
{
new ViewChoice{ Name="Page One", Brush=Brushes.Green},
new ViewChoice{ Name="Page Two", Brush=Brushes.Yellow},
};
private ViewChoice selectedViewChoice;
public ViewChoice SelectedViewChoice
{
get { return selectedViewChoice; }
set { selectedViewChoice = value; RaisePropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
and ViewChoice.
public class ViewChoice
{
public string Name { get; set; }
public SolidColorBrush Brush { get; set; }
public ICommand ChoiceCommand { get; set; }
}
Here's the zipped solution on onedrive:
https://1drv.ms/u/s!AmPvL3r385Qhgph8xc90FzTq8hrWQQ

Related

WPF - Async load of usercontrol using ContentControl so a loading animation can be displayed while loading

I have a usercontrol with some buttons, textblocks and a ContentControl that will load other (3) different usercontrols within the same usercontrol. The buttons from the parent usercontrol will stay so I can keep iterating through the other (3) usercontrols. Those (3) usercontrols contain 1, 2, or 3 DataGrids with several row, and this may take a second or two to load (at least while debugging). I want to display an animation to indicate this. However, I cannot load those user controls async in order to display the animation, which waits until the usercontrol is loaded.
I don't see why my code wouldn't work.
The parent usercontrol looks like this:
And when I click one of the three buttons at the bottom, a different usercontrol loads within the parent usercontrol, using the ContentControl.
The parent user control is something like this:
<UserControl>
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Top" >
<Control Visibility="{Binding LoadingVisilibity}" Style="{StaticResource BusyAnimationStyle}" Panel.ZIndex="10"/>
<ContentControl Content="{Binding ContentPanel}"></ContentControl>
</Grid>
</DockPanel>
</UserControl>
The BusyAnimationStyle just displays circles turning around.
<Style x:Key="BusyAnimationStyle" TargetType="{x:Type Control}">
<Setter Property="Background" Value="#9F000000"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Control">
<ControlTemplate.Resources>
<Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:0.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation1" BeginTime="00:00:00.1" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation2" BeginTime="00:00:00.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation3" BeginTime="00:00:00.3" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation4" BeginTime="00:00:00.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation5" BeginTime="00:00:00.5" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation6" BeginTime="00:00:00.6" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation7" BeginTime="00:00:00.7" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:00.8" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
<BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
<BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
<BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
<BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
<BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
<BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
<BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard0"/>
<StopStoryboard BeginStoryboardName="Storyboard1"/>
<StopStoryboard BeginStoryboardName="Storyboard2"/>
<StopStoryboard BeginStoryboardName="Storyboard3"/>
<StopStoryboard BeginStoryboardName="Storyboard4"/>
<StopStoryboard BeginStoryboardName="Storyboard5"/>
<StopStoryboard BeginStoryboardName="Storyboard6"/>
<StopStoryboard BeginStoryboardName="Storyboard7"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid>
<Canvas Height="60" Width="60">
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="15"/>
<Setter Property="Height" Value="15" />
<Setter Property="Fill" Value="#009B9B9B" />
</Style>
</Canvas.Resources>
<Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
<Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
<Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
<Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
<Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
<Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
<Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
<Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
<Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/>
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
private Visibility loadingVisilibity;
public Visibility LoadingVisilibity
{
get => loadingVisilibity;
set
{
loadingVisilibity = value;
OnPropertyChanged(nameof(LoadingVisilibity));
}
}
To change the Content of the ContentControl, I have three buttons each like:
private ICommand firstBtnCommand;
public ICommand FirstViewBtnCommand
{
get
{
return firstBtnCommand ?? (firstBtnCommand = new CommandHandler((param) => ChangeView("first"), true));
}
}
And the function:
private async void ChangeView(string view)
{
LoadingVisilibity = Visibility.Visible;
await Application.Current.Dispatcher.InvokeAsync(()=>
{
if (view == "first") { ContentPanel.Content = this.firstViewModel; }
else if (view == "second") { ContentPanel.Content = this.secondViewModel; }
else { ContentPanel.Content = this.thirdViewModel; }
});
LoadingVisilibity = Visibility.Collapsed;
}
I also tried:
await Application.Current.Dispatcher.BeginInvoke(
new ThreadStart(() =>
{
if (view == "first") { ContentPanel.Content = this.firstViewModel; }
else if (view == "second") { ContentPanel.Content = this.secondViewModel; }
else { ContentPanel.Content = this.thirdViewModel; }
}));
However, the animation doesn't happen. Sometimes I can see a bit just after the elements are loaded, but not while the ContentControl is loading.
I have done this before and usually goes like:
await Task.Run(() =>
{
if (view == "first") { ContentPanel.Content = this.firstViewModel; }
else if (view == "second") { ContentPanel.Content = this.secondViewModel; }
else { ContentPanel.Content = this.thirdViewModel; }
});
However, in this case tells me
The calling thread cannot access this object because a different thread owns it
I am lost now after trying so many different things, and I don't see anything wrong with my code.
How can I load the animation while the ContentControl content is loading? Is there a better way of doing this? Surely this looks like the right approach.
Let me know if there is more information that I can provide.

WPF user control not being visible on Visibility property change

Firstly I have a MVVM application whose main WPF Window contains many grid embedded and nested.
In one of these grids I have placed a user control to overlap the entire grid content as below:
View (Main WPF Window):
<controls:UCBusy Grid.Row="1" Grid.RowSpan="12"
Grid.ColumnSpan="3"
Visibility="{Binding Path=WaitMessageVisibility}"
Width="auto" Height="auto"/>
In view model I have defined the property bound:
private Visibility _waitMessageVisibility = Visibility.Visible;
public Visibility WaitMessageVisibility
{
get
{
return _waitMessageVisibility;
}
set
{
if (_waitMessageVisibility == value) return;
_waitMessageVisibility = value;
OnPropertyChanged("WaitMessageVisibility");
}
}
As you can see by default the visibility is set to Visible.
So my user control (spiner with message text on the right) should be visible but instead it is not being visible. What am I doing wrong? In order to make user control visible I set Panel.ZIndex to a higher value (100) when user control is visible using a ControlTemplate Trigger. See below.
User Control:
<UserControl x:Class="My.Apps.WPF.Demo.Controls.UCBusy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
<Color x:Key="FilledColor" A="255" B="222" R="176" G="196"/>
<Color x:Key="UnfilledColor" A="0" B="222" R="176" G="196"/>
<Style x:Key="BusyAnimationStyle" TargetType="Control">
<Setter Property="Background" Value="white" />
<Setter Property="Visibility" Value="Collapsed"/>
<Setter Property="Panel.ZIndex" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Control">
<ControlTemplate.Resources>
<Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsVisible" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
<BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
<BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
<BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
<BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
<BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
<BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
<BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard0"/>
<StopStoryboard BeginStoryboardName="Storyboard1"/>
<StopStoryboard BeginStoryboardName="Storyboard2"/>
<StopStoryboard BeginStoryboardName="Storyboard3"/>
<StopStoryboard BeginStoryboardName="Storyboard4"/>
<StopStoryboard BeginStoryboardName="Storyboard5"/>
<StopStoryboard BeginStoryboardName="Storyboard6"/>
<StopStoryboard BeginStoryboardName="Storyboard7"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Canvas Height="60" Width="60">
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="15"/>
<Setter Property="Height" Value="15" />
<Setter Property="Fill" Value="#009B9B9B" />
</Style>
</Canvas.Resources>
<Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
<Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
<Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
<Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
<Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
<Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
<Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
<Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
<Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/>
<Label Content="{Binding Path=WaitMessageText}"
FontSize="17"
Canvas.Left="60.5" Canvas.Top="11.5"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"/>
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Control Style="{StaticResource BusyAnimationStyle}" />
</UserControl>

Reusing WPF user control by parametrizing it does not work

In a MVVM application I have below user control.
From different areas of my WPF main Window, I am creating different instances of this user control so I would like to parametrize this user control in order to reuse it and show a different message in its label each time I create a new instance of it. In order to accomplish this, I have created a dependency property in the user control code-behind called MessageText and I have bound it to the label in the user control style.
User Control:
<UserControl x:Class="My.Apps.WPF.Demo.Controls.UCBusy"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
<Color x:Key="FilledColor" A="255" B="222" R="176" G="196"/>
<Color x:Key="UnfilledColor" A="0" B="222" R="176" G="196"/>
<Style x:Key="BusyAnimationStyle" TargetType="Control">
<Setter Property="Background" Value="white" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Control">
<ControlTemplate.Resources>
<Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
<BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
<BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
<BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
<BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
<BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
<BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
<BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard0"/>
<StopStoryboard BeginStoryboardName="Storyboard1"/>
<StopStoryboard BeginStoryboardName="Storyboard2"/>
<StopStoryboard BeginStoryboardName="Storyboard3"/>
<StopStoryboard BeginStoryboardName="Storyboard4"/>
<StopStoryboard BeginStoryboardName="Storyboard5"/>
<StopStoryboard BeginStoryboardName="Storyboard6"/>
<StopStoryboard BeginStoryboardName="Storyboard7"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Canvas Height="60" Width="60">
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="15"/>
<Setter Property="Height" Value="15" />
<Setter Property="Fill" Value="#009B9B9B" />
</Style>
</Canvas.Resources>
<Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
<Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
<Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
<Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
<Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
<Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
<Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
<Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
<Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/>
<Label Content="{Binding Path=MessageText}"
FontSize="17"
Canvas.Left="60.5" Canvas.Top="11.5"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"/>
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Control Style="{StaticResource BusyAnimationStyle}" />
</UserControl>
User Control Code-behind:
public partial class UCBusy : UserControl
{
public UCBusy()
{
InitializeComponent();
}
public static readonly DependencyProperty MessageTextProperty =
DependencyProperty.Register("MessageText", typeof(string), typeof(UCBusy));
public string MessageText
{
get
{
return this.GetValue(MessageTextProperty) as string;
}
set
{
this.SetValue(MessageTextProperty, value);
}
}
}
Then in the view, I bind the user control dependency property just created with properties in view model:
View Model:
<!-- Instance 1 -->
<controls:UCBusy MessageText="{Binding Path=WaitMessageText_1}" />
<!-- Instance 2 -->
<controls:UCBusy MessageText="{Binding Path=WaitMessageText_2}" />
... and in view model ...
View Model:
private string _waitMessageText_1 = "Hi there! I am message 1";
private string _waitMessageText_2 = "Hi there! I am message 2";
/// <summary>
/// Gets or sets the wait message text 1.
/// </summary>
public string WaitMessageText_1
{
get
{
return _waitMessageText_1;
}
set
{
if (_waitMessageText_1 == value) return;
_waitMessageText_1 = value;
OnPropertyChanged("WaitMessageText_1");
}
}
/// <summary>
/// Gets or sets the wait message text 2.
/// </summary>
public string WaitMessageText_2
{
get
{
return _waitMessageText_2;
}
set
{
if (_waitMessageText_2 == value) return;
_waitMessageText_2 = value;
OnPropertyChanged("WaitMessageText_2");
}
}
Finally, from view model I am setting these properties when needed but I note that my view is not being updated with the new messages I put, I mean, label in the user control does not display nothing. What am I doing wrong? I think I am missing something anywhere...
Note: In my case, Datacontext is always the same (I have set it to point to view model) so no need to change it each time I create a new instance of user control.
I would have you start by taking a look at a prior answer I provided that did a bunch of each step on a customized control, properties, styling, etc. It too is here at S/O
A couple of direct issues... Your "Style" declaration is based on a "Control", but your class is based on "Control", but your custom class is explicitly a "UCBusy" control, so "Control" has no idea what "MessageText" is for the style binding.
Also, you got by it partially because you declared as a different class type.
EDITED WITH FULL SAMPLE per my previous suggestions.
Here is source code that works to see all the parts. I created a new project "StackHelp" and have the following. Notice the merged dictionary is referring to the "component/MyClasses…" subfolder where my custom classes and corresponding .xaml resource dictionaries are created.
APP.XAML
<Application
x:Class="StackHelp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MyMainWindow.xaml">
<Application.Resources>
<!-- Generic up front for the entire application for the theme / styles to be used -->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/StackHelp;component/MyClasses/UCBusy.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
MyClasses\UCBusy.cs (within the subfolder in the project)
using System.Windows;
using System.Windows.Controls;
namespace StackHelp.MyClasses
{
public class UCBusy : UserControl
{
public UCBusy()
{
// just to default so style will allow us to see where this will present
// even just during design time sample.
MessageText = "My Sample Text";
}
public static readonly DependencyProperty MessageTextProperty
= DependencyProperty.Register("MessageText",
typeof(string), typeof(UCBusy));
public string MessageText
{
get { return GetValue(MessageTextProperty) as string; }
set { SetValue(MessageTextProperty, value); }
}
}
}
MyClasses\UCBusy.xaml (the xaml is specifically RESOURCE DICTIONARY item)
Two styles defined... a basic just as a stand-alone label just to see HOW the bindings get done... A SECOND one specifically to do your elaborate style. The "xmlns:myC" means the "myC" alias refers to the classes found within the "MyClasses" subfolder of the project per namespace.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myC="clr-namespace:StackHelp.MyClasses">
<!-- resource dictionary is in-itself a list of resources -->
<!-- Just a SIMPLE Style to test the proper bindings... as basic as possible to test context working -->
<Style TargetType="{x:Type myC:UCBusy}" x:Key="BusyAnimationStyleBasic">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type myC:UCBusy}" >
<Label Content="{TemplateBinding MessageText}"
FontSize="17"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Color x:Key="FilledColor" A="255" B="222" R="176" G="196"/>
<Color x:Key="UnfilledColor" A="0" B="222" R="176" G="196"/>
<!-- Now, your elaborate style with all animations...-->
<Style TargetType="{x:Type myC:UCBusy}" x:Key="BusyAnimationStyle">
<Setter Property="Background" Value="white" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type myC:UCBusy}" >
<ControlTemplate.Resources>
<Storyboard x:Key="Animation0" BeginTime="00:00:00.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse0" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse3" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse4" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse5" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse6" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="ellipse7" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsVisible" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Animation0}" x:Name="Storyboard0" />
<BeginStoryboard Storyboard="{StaticResource Animation1}" x:Name="Storyboard1"/>
<BeginStoryboard Storyboard="{StaticResource Animation2}" x:Name="Storyboard2"/>
<BeginStoryboard Storyboard="{StaticResource Animation3}" x:Name="Storyboard3"/>
<BeginStoryboard Storyboard="{StaticResource Animation4}" x:Name="Storyboard4"/>
<BeginStoryboard Storyboard="{StaticResource Animation5}" x:Name="Storyboard5"/>
<BeginStoryboard Storyboard="{StaticResource Animation6}" x:Name="Storyboard6"/>
<BeginStoryboard Storyboard="{StaticResource Animation7}" x:Name="Storyboard7"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="Storyboard0"/>
<StopStoryboard BeginStoryboardName="Storyboard1"/>
<StopStoryboard BeginStoryboardName="Storyboard2"/>
<StopStoryboard BeginStoryboardName="Storyboard3"/>
<StopStoryboard BeginStoryboardName="Storyboard4"/>
<StopStoryboard BeginStoryboardName="Storyboard5"/>
<StopStoryboard BeginStoryboardName="Storyboard6"/>
<StopStoryboard BeginStoryboardName="Storyboard7"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
<!--<StackPanel Orientation="Horizontal">
<TextBlock Text="{TemplateBinding MessageText}"/>
</StackPanel>-->
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<Grid>
<Canvas Height="60" Width="60">
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="15"/>
<Setter Property="Height" Value="15" />
<Setter Property="Fill" Value="#009B9B9B" />
</Style>
</Canvas.Resources>
<Ellipse x:Name="ellipse0" Canvas.Left="1.75" Canvas.Top="21"/>
<Ellipse x:Name="ellipse1" Canvas.Top="7" Canvas.Left="6.5"/>
<Ellipse x:Name="ellipse2" Canvas.Left="20.5" Canvas.Top="0.75"/>
<Ellipse x:Name="ellipse3" Canvas.Left="34.75" Canvas.Top="6.75"/>
<Ellipse x:Name="ellipse4" Canvas.Left="40.5" Canvas.Top="20.75" />
<Ellipse x:Name="ellipse5" Canvas.Left="34.75" Canvas.Top="34.5"/>
<Ellipse x:Name="ellipse6" Canvas.Left="20.75" Canvas.Top="39.75"/>
<Ellipse x:Name="ellipse7" Canvas.Top="34.25" Canvas.Left="7" />
<Ellipse Width="39.5" Height="39.5" Canvas.Left="8.75" Canvas.Top="8" Visibility="Hidden"/>
<Label Content="{TemplateBinding MessageText}"
FontSize="17"
Canvas.Left="60.5" Canvas.Top="11.5"
HorizontalContentAlignment="Center"
VerticalAlignment="Center"/>
</Canvas>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
MyMainWindow.xaml.cs (the main window for the startup of the application)
using System.ComponentModel;
using System.Windows;
namespace StackHelp
{
public partial class MyMainWindow : Window, INotifyPropertyChanged
{
public MyMainWindow()
{
DataContext = this;
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _waitMessageText_1 = "Hi there! I am message 1";
public string WaitMessageText_1
{
get
{
return _waitMessageText_1;
}
set
{
if (_waitMessageText_1 == value) return;
_waitMessageText_1 = value;
OnPropertyChanged("WaitMessageText_1");
}
}
private string _waitMessageText_2 = "Hi there! I am message 2";
public string WaitMessageText_2
{
get
{
return _waitMessageText_2;
}
set
{
if (_waitMessageText_2 == value) return;
_waitMessageText_2 = value;
OnPropertyChanged("WaitMessageText_2");
}
}
}
}
MyMainWindow.xaml (actual xaml for the main window)
Here, I have two instances, one using the BASIC style, second using the fully defined/spinner style.
<Window x:Class="StackHelp.MyMainWindow"
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:myC="clr-namespace:StackHelp.MyClasses"
Title="My Main Window" Height="250" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<!-- Instance 1 using the BASIC style version-->
<myC:UCBusy MessageText="{Binding WaitMessageText_1}"
Grid.Column="0" Style="{StaticResource BusyAnimationStyleBasic}" />
<!-- Instance 2 using the FINAL style version-->
<myC:UCBusy MessageText="{Binding WaitMessageText_2}"
Grid.Column="1" Style="{StaticResource BusyAnimationStyle}"/>
</Grid>
</Window>
Hope this finishes jump-starting you on your own styles and implementations.

Intermittent exception in storyboard in UWP/Winrt applcation

I am receiving the following exception intermittingly when triggering a storyboard on a user control through a View State.
WinRT information: Cannot resolve TargetProperty (Background).(SolidColorBrush.Color) on specified object
My storyboard is below -
<StackPanel Orientation="Horizontal">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="Connecting">
<Storyboard RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd1" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame Value="#F7F7F7" KeyTime="0:0:0" />
<DiscreteColorKeyFrame Value="#6CBF25" KeyTime="0:0:1" />
<DiscreteColorKeyFrame Value="#F7F7F7" KeyTime="0:0:5" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Bd1" Storyboard.TargetProperty="(BorderBrush).(SolidColorBrush.Color)">
<DiscreteColorKeyFrame Value="#919191" KeyTime="0:0:0" />
<DiscreteColorKeyFrame Value="#01851F" KeyTime="0:0:1" />
<DiscreteColorKeyFrame Value="#919191" KeyTime="0:0:5" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Bd1" Height="5" />
</StackPanel>
And how I trigger it
VisualStateManager.GoToState(this, "Connecting", false);
This visual state is generally triggered immediately on UserControl load.
Its failing because there isn't a SolidColorBrush defined on Bd1.
Background is of type Brush so you could initilaise with a SolidColorBrush like so and your animation should work. I added BorderBrush as well as you're animating that and a Width so you can see it on the screen
<Border x:Name="Bd1" Width="200" Height="5" Background="Red" BorderBrush="Red" />
Your border has no default color. Therefore you can´t access it from Storyboard.
This will work:
<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="BorderAnimationGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Connecting">
<Storyboard RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" Storyboard.TargetName="Bd1">
<EasingColorKeyFrame KeyTime="0" Value="#FFF7F7F7"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FF6CBF25"/>
<EasingColorKeyFrame KeyTime="0:0:5" Value="#FFF7F7F7"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="Bd1">
<EasingColorKeyFrame KeyTime="0" Value="#FF919191"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FF01851F"/>
<EasingColorKeyFrame KeyTime="0:0:5" Value="#FF919191"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Bd1" BorderBrush="#FF919191" BorderThickness="1" Height="5" Background="White">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior>
<Core:GoToStateAction StateName="Connecting"/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Border>
</StackPanel>

Display gif image

When I developed my WPF PC application, I used the following code to display my gif image, as I realized that there is no easy way of doing this:-
XAML:
<StackPanel Height="25" Name="stkProgressBar">
<wfi:WindowsFormsHost Background="Transparent" HorizontalAlignment="Center">
<winForms:PictureBox x:Name="pictureBoxLoading" Visible="False">
</winForms:PictureBox>
</wfi:WindowsFormsHost>
</StackPanel>
XAML.cs:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
this.pictureBoxLoading.Image = Properties.Resources.progressbar;
}
Now when I use the same approach to display the image in my WPF Browser (XBAP) application, it is not loading the page because of this xaml code? Any ideas why is that so and if there is any other way to display GIFs on a XBAP page?
Thanks,
Abhi.
==================
Updated at 27/07/2010 11:AM
Now I tried the following code:-
XAML:
<Image Name="Image1"></Image>
XAML.cs:
Stream imageStreamSource = new FileStream(#"C:\Inetpub\ExchangeRate\ExchangeRate\Image\progressbar.gif", FileMode.Open, FileAccess.Read, FileShare.Read);
GifBitmapDecoder decoder = new GifBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
Int32Animation anim = new Int32Animation(0, decoder.Frames.Count - 1, new Duration(new TimeSpan(0, 0, 0, decoder.Frames.Count / 10, (int)((decoder.Frames.Count / 10.0 - decoder.Frames.Count / 10) * 1000))));
anim.RepeatBehavior = RepeatBehavior.Forever;
BitmapSource bitmapSource = decoder.Frames[0];
Image1.Source = bitmapSource;
Image1.Stretch = Stretch.None;
It shows the image alright, but is not animated. I would appreciate any help in this regard.
Abhi.
After toiling for a day I worked it out using a different approach. Instead of using a gif image, I created a user control as follows:-
<UserControl.Resources>
<Color x:Key="FilledColor" A="255" B="112" R="147" G="160"/>
<Color x:Key="UnfilledColor" A="0" B="112" R="147" G="160"/>
<Storyboard x:Key="Animation0" FillBehavior="Stop" BeginTime="00:00:00.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_00" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation1" BeginTime="00:00:00.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_01" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation2" BeginTime="00:00:00.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_02" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation3" BeginTime="00:00:00.6" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_03" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation4" BeginTime="00:00:00.8" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_04" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation5" BeginTime="00:00:01.0" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_05" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation6" BeginTime="00:00:01.2" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_06" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="Animation7" BeginTime="00:00:01.4" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetName="_07" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.0" Value="{StaticResource FilledColor}"/>
<SplineColorKeyFrame KeyTime="00:00:01.6" Value="{StaticResource UnfilledColor}"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Animation0}"/>
<BeginStoryboard Storyboard="{StaticResource Animation1}"/>
<BeginStoryboard Storyboard="{StaticResource Animation2}"/>
<BeginStoryboard Storyboard="{StaticResource Animation3}"/>
<BeginStoryboard Storyboard="{StaticResource Animation4}"/>
<BeginStoryboard Storyboard="{StaticResource Animation5}"/>
<BeginStoryboard Storyboard="{StaticResource Animation6}"/>
<BeginStoryboard Storyboard="{StaticResource Animation7}"/>
</EventTrigger>
</UserControl.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" MinWidth="150" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Canvas Grid.Row="1" Grid.Column="1" Height="20" HorizontalAlignment="Left" VerticalAlignment="Top">
<Canvas.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="15"/>
<Setter Property="Height" Value="15" />
<Setter Property="Fill" Value="#FFFFFFFF" />
</Style>
<Style TargetType="Rectangle">
<Setter Property="Width" Value="12"/>
<Setter Property="Height" Value="13" />
<Setter Property="Fill" Value="#FFFFFFFF" />
<Setter Property="RadiusX" Value="2" />
<Setter Property="RadiusY" Value="2" />
</Style>
</Canvas.Resources>
<Rectangle x:Name="_00" Canvas.Top="6" Canvas.Left="15"></Rectangle>
<Rectangle x:Name="_01" Canvas.Top="6" Canvas.Left="30"></Rectangle>
<Rectangle x:Name="_02" Canvas.Top="6" Canvas.Left="45"></Rectangle>
<Rectangle x:Name="_03" Canvas.Top="6" Canvas.Left="60"></Rectangle>
<Rectangle x:Name="_04" Canvas.Top="6" Canvas.Left="75"></Rectangle>
<Rectangle x:Name="_05" Canvas.Top="6" Canvas.Left="90"></Rectangle>
<Rectangle x:Name="_06" Canvas.Top="6" Canvas.Left="105"></Rectangle>
<Rectangle x:Name="_07" Canvas.Top="6" Canvas.Left="120"></Rectangle>
</Canvas>
<!-- <TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" Foreground="#AAA" TextAlignment="Center" FontSize="15" Text="{Binding Source={StaticResource Model}, Path=StatusMessage}"/> -->
</Grid>
In the usercontrol class, I created method as follows:-
public void Show()
{
this.Visibility = Visibility.Visible;
}
public void Hide()
{
this.Visibility = Visibility.Hidden;
}
This link pointed me in this direction.

Resources