I'm trying to figure out how to animate the change from Visibile to Hidden for a WPF window. The way I currently have the application working is that the window is normally hidden and when I move the mouse to the side of the screen it pops out, I'm using a boolean to visibility converter to do that but what I would like to do is to have the application slide out more smoothly on mouse over as well as slide back in again afterwards.
I haven't don't anything with animations so I'm not sure how to do this. Firstly I'm not really sure what animation I should use the do this, secondly I'm not really sure whether I should trigger this on the "IsWindowVisibile" property in the viewmodel or if I should bind it to the VisibilityChanged event and thirdly I'm not sure if this is possible when the window size is variable.
[Edit]
If necessary I will 'take' an opacity solution but that's not exactly the 'sliding' effect I am trying to get.
I did something like that (opacity goes to 0 during 2 seconds and window hides): just look at code, it's simple
MainWindow.xaml:
<Storyboard x:Key="hideMe">
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:2" To="0.0"/>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:2" Value="{x:Static Visibility.Hidden}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="showMe">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:5" To="0.75"/>
</Storyboard>
MainWindow.xaml.cs
public void ShowMe() {
(FindResource("showMe") as Storyboard).Begin(this);
}
public void HideMe() {
(FindResource("hideMe") as Storyboard).Begin(this);
}
Just call HideMe()
or ShowMe()
instead of setting Visibility = Visibility.Hidden
in code
Edit
WPF is slow when moving windows, so if you need sliding animation:
Make a transparent window (AllowsTransparency="True" Background="Transparent" WindowStyle="None"
)
Put all your controls onto opaque panel (Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}"
)
Animate this panel's Margin.Left
from 0
to window's ActualWidth
, then hide a window - this will remove a problem of saving window size
Playing with a Window's Opacity
/Visibility
requires a simple DoubleAnimation
.
Example:
IsVisibleChanged += new DependencyPropertyChangedEventHandler(MainWindow_IsVisibleChanged);
void MainWindow_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
DoubleAnimation da = new DoubleAnimation()
{
From = (IsVisible) ? 0 : 1,
To = (IsVisible) ? 1 : 0,
Duration = TimeSpan.FromSeconds(1)
};
BeginAnimation(Window.OpacityProperty, da);
}
Problem:
For this to work as expected, you need to set AllowsTransparency
to True
on your window. If you don't set this, your window with Opacity
set to 0
will be Black
.
The problem is for this property to be True
, you need to have WindowStyle
as None
. Which means no frame around your window. That means no close, minimize, maximize, restore, title bar.
You have to provide a custom template (probably inherit Window
class) to put these buttons up there.