Animate UserControl in WPF? - wpf

I have two xaml file one is MainWindow.xaml and other is userControl EditTaskView.xaml.
In MainWindow.xaml it consists of listbox and when double clicked any item of listbox, it displays other window (edit window) from EditView userControl. I am trying to animate this userControl everytime whenever any item from the listbox is double clicked. I added some animation in userControl however the animation only gets run once. How can i make my animation run everytime whenever any item from the listbox is clicked?
MainWindow.xaml
<ListBox x:Name="lstBxTask" Style="{StaticResource ListBoxItems}" MouseDoubleClick="lstBxTask_MouseDoubleClick">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Rectangle Style="{StaticResource LineBetweenListBox}"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Taskname}" Style="{StaticResource TextInListBox}"/>
<Button Name="btnDelete" Style="{StaticResource DeleteButton}" Click="btnDelete_Click"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ToDoTask:EditTaskView x:Name="EditTask" Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Visibility="Collapsed"/>
In the MainWindow code, there is mouse double click event, which changes the visibility of EditTaskView to Visible.
Suggestions?

You haven't shown us your animation. Usually the animation does play everytime the event is triggered:
<UserControl.Resources>
<Storyboard x:Key="Storyboard1">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="LayoutRoot">
<EasingColorKeyFrame KeyTime="0" Value="#FFB62A2A"/>
<EasingColorKeyFrame KeyTime="0:0:4" Value="#FF2A32B6"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Control.MouseDoubleClick">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</UserControl.Triggers>

Thanks bitbonk, your code really help.
I think i figure out what was my problem. I had EventTrigger as FrameworkElement.Loaded instead of Control.MouseDoubleClick.
anyway the code looks like this:
<Storyboard x:Key="AnimateEditView">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="EditTask">
<EasingThicknessKeyFrame KeyTime="0" Value="0">
<EasingThicknessKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseOut"/>
</EasingThicknessKeyFrame.EasingFunction>
</EasingThicknessKeyFrame>
<EasingThicknessKeyFrame KeyTime="0:0:1.6" Value="0"/>
</ThicknessAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="EditTask">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource headerAnimation}"/>
<BeginStoryboard Storyboard="{StaticResource textBxAnimation}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Control.MouseDoubleClick">
<BeginStoryboard Storyboard="{StaticResource AnimateEditView}"/>
</EventTrigger>
</Window.Triggers>

Related

How to Execute a Storyboard of the events of any control in xaml in WPF?

I'm using C# WPF and have a Animation Style for the Border that is inside of a Grid that raise on MouseEnter event
<Style x:Key="Atash" TargetType="Border">
<Style.Triggers>
<EventTrigger RoutedEvent="UIElement.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.BlurRadius)" >
<EasingDoubleKeyFrame KeyTime="0" Value="12">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="37">
<EasingDoubleKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" >
<EasingThicknessKeyFrame KeyTime="0" Value="5,3">
<EasingThicknessKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingThicknessKeyFrame.EasingFunction>
</EasingThicknessKeyFrame>
</ThicknessAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" >
<EasingColorKeyFrame KeyTime="0" Value="#FF4CAF50">
<EasingColorKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#FF4CAF50"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style>
What I need:
when I set the Style of my Border to Border x:Name="border2" Style="{StaticResource Atash}" The animation starts when the MouseEnter event occurs on the Border itself (mouse on the border).
But I want my animation to be executed in all the events that I want according to several specified controls.
I mean that I can set this style on the grid as well : Grid Style="{StaticResource Atash}"
Why,
because I want this animation to run when the mouse is on the grid, not just for the border
Long story short : I want to do the animation on any event in any control that I want to call, but only in XAML. I don't want to use code behind
Thanks
May related link:
WPF/XAML: multiple controls using the same events - is there an easier way?
https://social.msdn.microsoft.com/Forums/vstudio/en-US/48b22609-9055-4d3b-8f26-b87305e2dc8e/how-to-handle-child-event-in-parent-control?forum=wpf
start wpf animation from other element
https://www.codeproject.com/Tips/227733/Passing-events-from-child-to-parent-controls-built
.
Update
Full XAML Code:
<Window x:Class="WpfApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp11"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style x:Key="Atash" TargetType="FrameworkElement">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)">
<EasingThicknessKeyFrame KeyTime="0:0:0.2" Value="1,1,10,1">
<EasingThicknessKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingThicknessKeyFrame.EasingFunction>
</EasingThicknessKeyFrame>
</ThicknessAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0:0:0.2" Value="#FF23A232">
<EasingColorKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard x:Name="DoOnOut">
<ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)">
<SplineThicknessKeyFrame KeyTime="0" Value="1,1,10,1"/>
<EasingThicknessKeyFrame KeyTime="0:0:0.2" Value="1">
<EasingThicknessKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingThicknessKeyFrame.EasingFunction>
</EasingThicknessKeyFrame>
</ThicknessAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="0" Value="#FF23A232"/>
<EasingColorKeyFrame KeyTime="0:0:0.2" Value="White">
<EasingColorKeyFrame.EasingFunction>
<ExponentialEase EasingMode="EaseInOut"/>
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Background="#FF1B1B1C">
<Grid x:Name="GrdBtn2" Style="{StaticResource Atash}" Margin="323,167,345,135">
<Border x:Name="border2" Visibility="Visible" BorderBrush="White" BorderThickness="5,3" CornerRadius="80" Cursor="Hand" Width="auto" Height="auto" Background="#FF4CAF50">
<Border.Effect>
<DropShadowEffect Color="White" BlurRadius="12" ShadowDepth="0"/>
</Border.Effect>
</Border>
<TextBlock Text=" Automasion" LineStackingStrategy="MaxHeight" LineHeight="20" TextAlignment="Center" Width="auto" Height="auto" TextWrapping="Wrap" Margin="25,22,27,21" Foreground="White" Background="{x:Null}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Grid>
Error On MouseEnter of Grid:
System.InvalidOperationException: ''BorderBrush' property does not point to a DependencyObject in path '(0).(1)'.'
If you set the TargetType of the Style to FrameworkElement, you can apply it to any FrameworkElement including a Grid and a Border:
<Style x:Key="Atash" TargetType="FrameworkElement">
...
Obviously you cannot animate the BorderThickness of anything else than a Border though.
Your animation also assumes that the Background of the element to be animated is set to a SolidColorBrush and that it has a DropShadowEffect applied.

Animate an image inside of a tooltip of a button

For the application I am working on, I need an animation.
The problem is, that the animation is in a tooltip.
So I have a button and whenever I move over the button the tooltip comes up. The tooltip shows a short information text (Textblock) and after about two seconds he shall expand and show an image.
Since I am an XAML-only developer, which means I have no clue about C# and therefore I have no idea about binding to a viewmodel, I am looking for a way to do this with triggers and storyboards.
I have already achieved that effect with an Event Trigger, who reacts to the Routed Event Loaded. The problem is, that this works "only" once, when the Tooltip is loaded the first time.
Here is my code:
<Button Width="100" Height="100">
<Button.ToolTip>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Here is some text!"></TextBlock>
<Image Grid.Row="1" Visibility="Collapsed" Source="MyPicture.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Visibility"
Duration="0"
BeginTime="0:0:2">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
</Button.ToolTip>
</Button>
Is there a better Routed Event than "Loaded" or do I have to make my own Routed Event? Can I link the Event to the Button, like "When Button IsMouseOver is true do this with the image"?
Or is there a complete better way?
Nevertheless, solutions regarding a way with C# are also welcomed.
Thanks for any advices,
Gerrit
A DataTrigger on the ToolTip's Visibility, with Enter and Exit actions should work. Note the explicit <ToolTip>...</ToolTip>
<Button Width="100" Height="100">
<Button.ToolTip>
<ToolTip>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Here is some text!"></TextBlock>
<Image Grid.Row="1" Visibility="Collapsed" Source="MyPicture.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible, RelativeSource={RelativeSource AncestorType=ToolTip}}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Visibility"
Duration="0"
BeginTime="0:0:2">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Visibility"
Duration="0">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Grid>
</ToolTip>
</Button.ToolTip>
</Button>
Since you do not set the FillBehavior property in your animation, it is set to HoldEnd (i.e. the animation holds its value after it reaches the end of its active period). So you need just an "opposite" animation to reset the Visibility value:
<Image Grid.Row="1" Visibility="Collapsed" Source="MyPicture.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Visibility"
Duration="0"
BeginTime="0:0:2">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Unloaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="Visibility"
Duration="0"
BeginTime="0:0:0">
<DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
So the second animation will begin when the image is unloaded, has no duration and resets the Visibility value.

How to play Storyboard in ViewModel?

I defiend a storyborad in View
<Storyboard x:Key="ExpandAdd" >
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="AddUsers" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Visibility.Collapsed}"/>
<DiscreteObjectKeyFrame KeyTime="00:00:00.3000000" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="DetailBorder" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0.4"/>
</DoubleAnimationUsingKeyFrames>
<BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="DetailBorder" Storyboard.TargetProperty="(UIElement.IsEnabled)">
<DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="False"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
I have a button and bind to a relaycommand .
<Button x:Name="AddUserButton" Content="اضافه">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding AddUsers}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
I want to play storyboard when RelayCommand(AddUsers) is execute.
You should not access Storyboard from your ViewModel. It defeats the purpose of MVVM altogether.
You can apply storyboard on Button.LostMouseCapture event which gets raised after your command gets called on Click event -
<Button x:Name="AddUserButton" Content="اضافه">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding AddUsers}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.LostMouseCapture">
<BeginStoryboard Storyboard="{StaticResource ExpandAdd}">
</EventTrigger>
</Button.Triggers>
</Button>
Actually, this is relatively easy to do by using a DataTrigger that is bound to a property in the ViewModel, thus triggering the Storyboard from the MV while still maintaining separation of concerns. Here's a very brief example where a Storyboard grows an image in size in response to a bool in the VM changing to True.
<Image
Grid.Row="0"
x:Name="LockImage"
Source="/StoryboardManagerExample;component/Resources/LockedPadlock.png"
Width="50"
RenderTransformOrigin="0.5,0.5">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="ptScale" ScaleX="1" ScaleY="1"/>
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</Image.RenderTransform>
<Image.Style>
<Style>
<Style.Triggers>
<DataTrigger
Binding="{Binding RunStoryboard}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Width"
From="50"
To="100"
Duration="0:0:1"
RepeatBehavior="1x"
AutoReverse="True"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
You could call the Storyboard from a code-behind as long as you assigned it x:Name. But then, you'd need to implement a button_click event handler, not a command for the ViewModel.
If you're using MVVM then you should really abide by the principle that the ViewModel should not "know" about specifics of the View.
Please don't trigger the storyboard from the viewmodel. If you do then there is no point having a viewmodel.
Implement any code for the relay command in the code behind of the view, then if needed you can call through to the viewmodel to do anything
that is viewmodel specific. When you reference the storyboard from the code behind of the view you can just refer to it by name.
For UWP: You can define your storyboard in VisualStates and run it by changing property in ViewModel. If you change IsRefreshWorking property to true animation begins.
Define VisualState, using IsTrueTrigger:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="RefreshProgressVisualStates">
<VisualState x:Name="NotWorkingVisualState" />
<VisualState x:Name="WorkingVisualState">
<Storyboard AutoReverse="False" RepeatBehavior="Forever">
<DoubleAnimation Duration="0:0:1" To="360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="RefreshIcon" />
</Storyboard>
<VisualState.StateTriggers>
<StateTrigger IsActive="{x:Bind ViewModel.IsRefreshWorking, Mode=OneWay}" />
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
AppBarButton with animation:
<AppBarButton>
<AppBarButton.Icon>
<SymbolIcon x:Name="RefreshIcon" Symbol="Refresh" RenderTransformOrigin="0.5,0.5" >
<SymbolIcon.RenderTransform>
<CompositeTransform/>
</SymbolIcon.RenderTransform>
</SymbolIcon>
</AppBarButton.Icon>
</AppBarButton>

MouseEnter and MouseLeave

I have a user control in WPF. I have a button control within the control. I want the control to fade in and out when the mouse enters and leaves the control. The problem is when the mouse enters the button and leaves the control, it fades. Below is the code.
<UserControl x:Class="WpfPresentationEditor.PresentationWindowControl"
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"
d:DesignHeight="68" d:DesignWidth="793">
<UserControl.Resources>
<Storyboard x:Key="onMouseEnter">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="onMouseLeave">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard x:Name="onMouseEnter_BeginStoryBoard" Storyboard="{StaticResource onMouseEnter}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard x:Name="onMouseLeave_BeginStoryBoard" Storyboard="{StaticResource onMouseLeave}"/>
</EventTrigger>
<EventTrigger RoutedEvent="UserControl.Loaded">
<BeginStoryboard Storyboard="{StaticResource onMouseLeave}" />
</EventTrigger>
</UserControl.Triggers>
<Grid x:Name="LayoutRoot" Opacity=".5">
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent"></Canvas>
<Button Click="btnClose_Click" Height="44" HorizontalAlignment="Left" Name="btnClose" VerticalAlignment="Center" Width="44" Margin="12,12,0,12">
<Button.Background>
<ImageBrush ImageSource="images/exit.png" />
</Button.Background>
</Button>
</Grid>
This is what I ended up doing to make this work as desired.
I changed the RoutedEvent to UserControl.MouseEnter rather than Mouse.MouseEnter.
Then I created my own user control and created an Image button like this http://blogs.msdn.com/b/knom/archive/2007/10/31/wpf-control-development-3-ways-to-build-an-imagebutton.aspx.
So my altered code now looks like this....
<UserControl x:Class="WpfPresentationEditor.PresentationWindowControl"
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"
d:DesignHeight="68" d:DesignWidth="793" xmlns:my="clr-namespace:WpfPresentationEditor">
<UserControl.Resources>
<ImageBrush x:Key="exitImage" ImageSource="images/exit.png"/>
<!--These are the story boards for the control-->
<Storyboard x:Key="onMouseEnter">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="onMouseLeave">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="LayoutRoot">
<EasingDoubleKeyFrame KeyTime="0:0:3" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="UserControl.MouseEnter">
<BeginStoryboard x:Name="onMouseEnter_BeginStoryBoard" Storyboard="{StaticResource onMouseEnter}"/>
</EventTrigger>
<EventTrigger RoutedEvent="UserControl.MouseLeave">
<BeginStoryboard x:Name="onMouseLeave_BeginStoryBoard" Storyboard="{StaticResource onMouseLeave}"/>
</EventTrigger>
<EventTrigger RoutedEvent="UserControl.Loaded">
<BeginStoryboard Storyboard="{StaticResource onMouseLeave}" />
</EventTrigger>
</UserControl.Triggers>
<StackPanel x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Horizontal" Background="Black">
<my:ImageButtonControl ButtonBase.Click="btnClose_Click" x:Name="imageButtonControl1" Width="44" Image="images/exit.png" Height="44"/>
</StackPanel>
I would make 2 controls, one containing everything but your button and another one with just the button.
Then put them both in a grid so they will stack upon each other, and voila.

How to make a looped TranslateTransform?

I have a scrolling text line, and I need to achieve effect that immediately after the end of the text, start of the same text will appear. Any ideas?
UPD text is static (doesn't change)
Current animation code is like this:
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation From="200" To="-200" Storyboard.TargetName="translate"
Storyboard.TargetProperty="Y" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
It works ok, but it jerks when reaches end (and jumps back to the start). I need to avoid this.
If the text length is static, the easiest way to do this is to create multiple copies of the text offscreen and have the copy/copies animate to the same position as the original. If you have an animation loop this way, there will be no "jerk"
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Class="SilverlightApplication3.MainPage"
Width="200" Height="480">
<UserControl.Resources>
<Storyboard x:Name="TextScrollStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="offscreenTextBlock" RepeatBehavior="Forever">
<EasingDoubleKeyFrame KeyTime="0" Value="-200"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Storyboard.TargetName="textBlock" RepeatBehavior="Forever">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="200"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<i:Interaction.Triggers>
<i:EventTrigger>
<ei:ControlStoryboardAction Storyboard="{StaticResource TextScrollStoryboard}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid x:Name="LayoutRoot" Background="#FFBBBBBB">
<TextBlock x:Name="textBlock" Text="This is some text" RenderTransformOrigin="0.5,0.5" >
<TextBlock.RenderTransform>
<CompositeTransform TranslateX="0"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock x:Name="offscreenTextBlock" Text="This is some text" RenderTransformOrigin="0.5,0.5" >
<TextBlock.RenderTransform>
<CompositeTransform TranslateX="-200"/>
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
Check for a property "RepeatCount" (if memory serves me right), you can set it to infinity.

Resources