Have a button that gets animated when a IsBusy boolean property on the ViewModel is True:
<Button x:Name="button" Grid.Row="4"
Command="{Binding QuitCommand}"
Content="{x:Static r:Resources.Close}"
RenderTransformOrigin="0.5,0.5">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource TestStoryboard}"/>
</DataTrigger.EnterActions>
</DataTrigger> **<-- here is line 167 position 27**
</Style.Triggers>
</Style>
</Button.Style>
<Button.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Button.RenderTransform>
</Button>
Storyboard:
<Window.Resources>
<Storyboard x:Key="TestStoryboard">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="25"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="180"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
If I initialize the IsBusy property to false and then launch the animation later, then everything works.
If I initialize the IsBusy property to true then I get the following errors:
'[Unknown]' property does not point to a DependencyObject in path
'(0).(1)[2].(2)'. 'Set property
'System.Windows.FrameworkElement.Style' threw an exception.' Line
number '167' and line position '27'.
ViewModel:
public const string IsBusyPropertyName = "IsBusy";
private bool _IsBusy = true;
public bool IsBusy
{
get
{
return _IsBusy;
}
set
{
if (_IsBusy == value)
{
return;
}
RaisePropertyChanging(IsBusyPropertyName);
_IsBusy = value;
RaisePropertyChanged(IsBusyPropertyName);
}
}
Timing issue?
Set
<Button.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Button.RenderTransform>
before
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource TestStoryboard}"/>
</DataTrigger.EnterActions>
</DataTrigger> **<-- here is line 167 position 27**
</Style.Triggers>
</Style>
</Button.Style>
If it's already true then it calls storyboard before RenderTransform is set, I believe.
Related
I tried to execute animation with DataTrigger but it don't reise up.
Program don't throw any exception and errors.
Can someone explain why animation don't Start ?
Here is my storyboard
<Storyboard x:Key="storyboard2" AutoReverse="True" RepeatBehavior="Forever" Duration="00:01:00">
<DoubleAnimation Storyboard.TargetProperty="(Rectangle.RenderTransform).(ScaleTransform.ScaleX)" Storyboard.Target="{Binding Source={x:Reference RectangleScaleFrom}}" To="4" From="1"/>
<DoubleAnimation Storyboard.TargetProperty="(Rectangle.RenderTransform).(ScaleTransform.ScaleY)" Storyboard.Target="{Binding Source={x:Reference RectangleScaleFrom}}"
From="4" To="1"/>
</Storyboard>"
Here Is DataTrigger to start and Stop Animation
<DataTrigger Binding="{Binding RunAnimation}" Value="True" x:Key="Start">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="BeginScaleFrom" Storyboard="{StaticResource storyboard2}"/>
<!--<BeginStoryboard x:Name="BeginScaleTo" Storyboard="{StaticResource storyboard2}"/>-->
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding RunAnimation}" Value="False" x:Key="Stop">
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginScaleFrom"/>
<!--<StopStoryboard BeginStoryboardName="BeginScaleTo"/>-->
</DataTrigger.ExitActions>
</DataTrigger>
Here is Button
<ToggleButton Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="50,20,50,30" FontSize="20" x:Name="StartButton" Style="{StaticResource StartStopButtonStyle}" Width="100" Height="50" Command="{Binding StartAnimation}">
</ToggleButton>
And Command to start
private bool _StartAnim = false;
public bool RunAnimation
{
get => _StartAnim;
set
{
_StartAnim = value;
RaisePropertyChanged(nameof(RunAnimation));
}
}
public RelayCommand StartAnimation { get; private set; }
public MainViewModel()
{
StartAnimation = new RelayCommand(() => RunAnimation = !RunAnimation);
}
Something like this should work:
<Window.Resources>
<Storyboard x:Key="storyboard2">
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleX"
To="4" From="1" AutoReverse="True"
RepeatBehavior="Forever" Duration="00:00:10"/>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.ScaleY"
From="4" To="1" AutoReverse="True"
RepeatBehavior="Forever" Duration="00:00:10"/>
</Storyboard>
</Window.Resources>
<Rectangle Width="100" Height="100" Fill="Red">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="RenderTransform">
<Setter.Value>
<ScaleTransform/>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding RunAnimation}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="BeginScaleFrom"
Storyboard="{StaticResource storyboard2}"/>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="BeginScaleFrom"/>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
I am having trouble getting my tabitem to flash when the value for newCall is true. I think i have the Xaml correct but i am not sure how to bind it behind in code. When the variable new Call is set to true i would like my tabitem to flash.
<TabItem.Style>
<Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource MetroTabItem}">
<Style.Resources>
<Storyboard x:Key="flashAnimation" >
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" AutoReverse="True" Duration="0:0:0.5" RepeatBehavior="Forever" />
</Storyboard>
</Style.Resources>
<Style.Triggers>
<DataTrigger Binding="{Binding newCall}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard Name="flash" Storyboard="{StaticResource flashAnimation}" />
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</TabItem.Style>
Your ViewModel has to implement INotifyPropertyChanged. In the ViewModel add the following Code:
private bool _newCall;
public bool newCall
{
get { return _newCall; }
set
{
_newCall = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("newCall"));
}
}
}
and change Binding="{Binding newCall} to Binding="{Binding newCall, UpdateSourceTrigger=PropertyChanged}"
Then, the TabItem will start flashing as soon as newCall is set to true
Hello I have a problem accessing User Control Properties. My User Control Looks like this:
<UserControl.Resources>
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnChecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="25"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnUnchecking">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="slider" Storyboard.TargetProperty="(FrameworkElement.Margin)">
<SplineThicknessKeyFrame KeyTime="00:00:00.3000000" Value="1,1,1,1"/>
</ThicknessAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border Name="Border">
<DockPanel x:Name="dockPanel">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center"/>
<Grid Width="50" x:Name="grid">
<TextBlock Text="ON" TextWrapping="Wrap" FontWeight="Bold" FontSize="12" HorizontalAlignment="Right" Margin="0,0,3,0"/>
<TextBlock HorizontalAlignment="Left" Margin="2,0,0,0" FontSize="12" FontWeight="Bold" Text="OFF" TextWrapping="Wrap"/>
<Border HorizontalAlignment="Left" x:Name="slider" Width="23" BorderThickness="1,1,1,1" CornerRadius="3,3,3,3" RenderTransformOrigin="0.5,0.5" Margin="1,1,1,1">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Border.RenderTransform>
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#FF4490FF" Offset="1"/>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF8AB4FF" Offset="1"/>
<GradientStop Color="#FFD1E2FF" Offset="0"/>
</LinearGradientBrush>
</Border.Background>
</Border>
</Grid>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="False">
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard"/>
</Trigger.ExitActions>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard"/>
</Trigger.EnterActions>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<Grid>
<CheckBox x:Name="CheckBox1" HorizontalAlignment="Center"
Style="{DynamicResource CheckBoxStyle1}"
VerticalAlignment="Center"
Checked="CheckBox1_OnChecked"
Unchecked="CheckBox1_OnUnchecked"/>
</Grid>
And in the code behind(some of a great number of getters/setters):
public new Brush Background
{
get
{
var border = CheckBox1.Template.LoadContent() as Border;
return border == null ? Brushes.White : border.Background;
}
set
{
var border = CheckBox1.Template.LoadContent() as Border;
if (border == null) return;
border.Background = value;
}
}
public new Thickness BorderThickness
{
get
{
var border = CheckBox1.Template.LoadContent() as Border;
return border == null ? new Thickness(0) : border.BorderThickness;
}
set
{
var border = CheckBox1.Template.LoadContent() as Border;
if (border == null) return;
border.BorderThickness = value;
}
}
public new Brush BorderBrush
{
get
{
var border = CheckBox1.Template.LoadContent() as Border;
return border == null ? Brushes.Transparent : border.BorderBrush;
}
set
{
var border = CheckBox1.Template.LoadContent() as Border;
if (border == null) return;
border.BorderBrush = value;
}
}
And also i use it in another window like this(SliderOnOff is the name of my control):
<switch:SliderOnOff x:Name="SliderOnOff"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsEnabled="True"
Background="Green"
BorderThickness="10"
BorderBrush="HotPink"
IsChecked="True"
BorderRadius="5"
Checked="SliderOnOff_OnChecked"
UnChecked="SliderOnOff_OnUnChecked">
</switch:SliderOnOff>
I thought it works fine, because setting properties in xaml leaded to changing in properties of control.
BUT!!!!!!
When I try to change it programmatically ( Slider.Background = Brushes.HotPink; ), nothing happens, it doesnt change. Also this part of properties doesnt work at all(none in xaml, none in code):
public CornerRadius BorderRadius
{
get
{
var border = CheckBox1.Template.LoadContent() as Border;
return border == null ? new CornerRadius(0) : border.CornerRadius;
}
set
{
var border = CheckBox1.Template.LoadContent() as Border;
if (border == null) return;
border.CornerRadius = new CornerRadius(value.TopLeft,value.TopRight,value.BottomRight,value.BottomLeft);
}
}
Can you help me with it?
I think your ui hast to be informed about the changes.
Have a look at: http://www.codeproject.com/Articles/42536/List-vs-ObservableCollection-vs-INotifyPropertyCha
Your class must implement INotifyPropertyChanged, and within your "set" part you have to raise that event.
like:
public class MainViewModel : ViewModelBase, INotifyPropertyChanged
{
public KeyInfo SelectedKeyInfo
{
get
{
return _SelectedKeyInfo;
}
set
{
_SelectedKeyInfo = value;
OnPropertyChanged("SelectedKeyProducts");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
Basically I tried to make a marquee with 2 Labels that when one goes invisible, the second one starts it's animation so it goes smooth from left to right and the text is always visible. My problem is that it does work at start but when I retry that code (second time at run time so the old animation stops, it refresh the text and start the animation again) the second label freezes when it was and it's left property of it's canvas doesn't change (Canvas.SetLeft(L_Content_Second, -L_Content_Second.ActualWidth))
C#
it's a function called StartAnimation(); It's fired when content of L_Content and L_Content_Second changes
DoubleKeyFrameCollection collection = new DoubleKeyFrameCollection();
collection.Add(
new LinearDoubleKeyFrame(
-L_Content.ActualWidth,
KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0)))
);
if (L_Content.ActualWidth > this.ActualWidth)
{
collection.Add(
new LinearDoubleKeyFrame(
this.ActualWidth - (L_Content.ActualWidth / 2),
KeyTime.FromTimeSpan(TimeSpan.FromSeconds(15)))
);
collection.Add(
new LinearDoubleKeyFrame(
this.ActualWidth * 2,
KeyTime.FromTimeSpan(TimeSpan.FromSeconds(30)))
);
}
else
{
collection.Add(
new LinearDoubleKeyFrame(
this.ActualWidth - L_Content.ActualWidth,
KeyTime.FromTimeSpan(TimeSpan.FromSeconds(15)))
);
collection.Add(
new LinearDoubleKeyFrame(
this.ActualWidth + (this.ActualWidth - L_Content.ActualWidth),
KeyTime.FromTimeSpan(TimeSpan.FromSeconds(30)))
);
}
animK.KeyFrames = collection;
animK.Duration = TimeSpan.FromSeconds(30);
animK2.KeyFrames = collection;
animK2.BeginTime = TimeSpan.FromSeconds(15);
animK2.Duration = TimeSpan.FromSeconds(30);
animK.AutoReverse = false;
animK2.AutoReverse = false;
animK.FillBehavior = FillBehavior.Stop;
animK.RepeatBehavior = RepeatBehavior.Forever;
animK2.FillBehavior = FillBehavior.Stop;
animK2.RepeatBehavior = RepeatBehavior.Forever;
Canvas.SetLeft(L_Content_Second, -L_Content_Second.ActualWidth); //This works at start, then it doesn't any more
L_Content_Second.Visibility = System.Windows.Visibility.Visible;
L_Content.BeginAnimation(Canvas.LeftProperty, animK, HandoffBehavior.SnapshotAndReplace);
L_Content_Second.BeginAnimation(Canvas.LeftProperty, animK2, HandoffBehavior.SnapshotAndReplace);
XAML
<UserControl x:Name="userControl" x:Class="Supreme.Components.ScrollLabel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="18" Width="300" MouseDoubleClick="UserControl_MouseDoubleClick_1" Background="#00000000">
<Canvas x:Name="Container">
<Label x:Name="L_Content" Content="" HorizontalAlignment="Left" Padding="0" Height="18" Foreground="{Binding Foreground, ElementName=userControl}" VerticalAlignment="Top"/>
<Label x:Name="L_Content_Second" Content="" HorizontalAlignment="Left" Padding="0" Height="18" Foreground="{Binding Foreground, ElementName=userControl}" SizeChanged="L_Content_SizeChanged" VerticalAlignment="Top"/>
</Canvas>
</UserControl>
I tried to attempt the same via XAML
below is the sample for same, run it and see if this does what you are looking for.
<Canvas x:Name="Container">
<Canvas.Resources>
<l:PositionConverter xmlns:l="clr-namespace:CSharpWPF"
x:Key="PositionConverter" />
<Storyboard x:Key="marquee">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="L_Content"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(Canvas.Left)"
Duration="0:0:10">
<SplineDoubleKeyFrame KeyTime="0:0:0"
Value="{Binding ActualWidth, ElementName=L_Content, Converter={StaticResource PositionConverter}}" />
<SplineDoubleKeyFrame KeyTime="0:0:5"
Value="{Binding ActualWidth,ElementName=Container}" />
<SplineDoubleKeyFrame KeyTime="0:0:10"
Value="{Binding ActualWidth,ElementName=Container}" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="L_Content_Second"
RepeatBehavior="Forever"
Storyboard.TargetProperty="(Canvas.Left)"
Duration="0:0:10">
<SplineDoubleKeyFrame KeyTime="0:0:0"
Value="{Binding ActualWidth, ElementName=L_Content_Second, Converter={StaticResource PositionConverter}}" />
<SplineDoubleKeyFrame KeyTime="0:0:5"
Value="{Binding ActualWidth, ElementName=L_Content_Second, Converter={StaticResource PositionConverter}}" />
<SplineDoubleKeyFrame KeyTime="0:0:10"
Value="{Binding ActualWidth,ElementName=Container}" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
<TextBox x:Name="L_Content"
Foreground="Red"
Text="first" />
<TextBox x:Name="L_Content_Second"
Foreground="Green"
Text="second">
</TextBox>
<Button Content="Start" Canvas.Top="30">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard Storyboard="{StaticResource marquee}" />
</EventTrigger>
</Button.Triggers>
</Button>
<Canvas.Triggers>
<EventTrigger SourceName="L_Content"
RoutedEvent="SizeChanged">
<BeginStoryboard Storyboard="{StaticResource marquee}" />
</EventTrigger>
<EventTrigger SourceName="L_Content_Second"
RoutedEvent="SizeChanged">
<BeginStoryboard Storyboard="{StaticResource marquee}" />
</EventTrigger>
<EventTrigger RoutedEvent="SizeChanged">
<BeginStoryboard Storyboard="{StaticResource marquee}" />
</EventTrigger>
</Canvas.Triggers>
</Canvas>
I've used textbox in this example for easy value change, also for this I have created a converter
namespace CSharpWPF
{
public class PositionConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return -System.Convert.ToDouble(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
If buttons are dynamically added in wpf from code behind how can you add tooltips to them or text to the actual button?
This is what you would do in windows forms but I dont think you can do it in wpf:
partial class Window1
{
void button3Click(object sender, RoutedEventArgs e)
{
//toolTip1.SetToolTip(this.button1, "My button1");
MessageBox.Show("action 3");
}
void button2Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("action 2");
}
void button1Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("action 1");
}
public Window1()
{
this.InitializeComponent();
populateButtons();
//ToolTip toolTip1 = new ToolTip();
//// Set up the delays for the ToolTip.
//toolTip1.AutoPopDelay = 5000;
//toolTip1.InitialDelay = 1000;
//toolTip1.ReshowDelay = 500;
//// Force the ToolTip text to be displayed whether or not the form is active.
//toolTip1.ShowAlways = true;
}
public void populateButtons()
{
int xPos;
int yPos;
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3Click })
{
Button foo = new Button();
Style buttonStyle = Window.Resources["CurvedButton"] as Style;
int sizeValue = 100;
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(200);
yPos = ranNum.Next(250);
//canvas1.HorizontalAlignment = HorizontalAlignment.Left;
//canvas1.VerticalAlignment = VerticalAlignment.Top;
//canvas1.Margin = new Thickness(xPos, yPos, 0, 0);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Style = buttonStyle;
foo.Click += routedEventHandler;
LayoutRoot.Children.Add(foo);
}
}
}
}
As for adding text im not sure?
Here is the xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="en-US"
x:Class="DynamicButtons.Window1"
x:Name="Window"
Title="Dynamic Buttons"
Width="840" Height="600" Icon="shape_group.png">
<Window.Resources>
<Style x:Key="CurvedButton" BasedOn="{x:Null}" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnMouseMove1">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFFFFFFF"/>
<SplineColorKeyFrame KeyTime="00:00:00.3000000" Value="#7CE1DBDB"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.66"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.66"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnMouseLeave1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1.78"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1.78"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnClick1">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.2000000" Value="#FFFFFFFF"/>
<SplineColorKeyFrame KeyTime="00:00:00.3000000" Value="#BFA0D1E2"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Rectangle RenderTransformOrigin="1,1" Fill="#3FFFFFFF" Stroke="{x:Null}" RadiusX="11" RadiusY="11" x:Name="rectangle">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click">
<BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard x:Name="OnMouseLeave1_BeginStoryboard" Storyboard="{StaticResource OnMouseLeave1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard x:Name="OnMouseMove1_BeginStoryboard" Storyboard="{StaticResource OnMouseMove1}"/>
</EventTrigger>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsPressed" Value="True"/>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF3F3F3" Offset="0"/>
<GradientStop Color="#FFEBEBEB" Offset="0.5"/>
<GradientStop Color="#FFDDDDDD" Offset="0.5"/>
<GradientStop Color="#E1CDCDCD" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
</Window.Triggers>
<Window.Background>
<LinearGradientBrush EndPoint="0.484,0.543" StartPoint="0.478,0.009">
<GradientStop Color="Gray" Offset="1"/>
<GradientStop Color="DarkGray" Offset="0"/>
</LinearGradientBrush>
</Window.Background>
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Canvas Height="282" HorizontalAlignment="Left" Margin="12,12,0,0" Name="canvas1" VerticalAlignment="Top" Width="343" />
</Grid>
</Window>
Have you tried to use the Tooltip-Property?
You can assign a ToolTip to the ToolTip property of the Button and set the Content property to the text you want to display:
ToolTip t = new ToolTip();
t.Content = "Something helpful";
Button b = new Button;
b.Content = "Hover over me";
b.ToolTip = t;
If you want to make the button show up apparently you have to add it to the panel it should belong to - which I assume is the canavs:
// add the button to the canvas
canvas1.Children.Add(b);
// set the position of the button on the canvas
Canvas.SetLeft(b, 20);
Canvas.SetTop(b, 20);