Reputation: 1907
I've got an app that has a few nested Grids, like so:
<Grid x:Name="ContainerGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
[main content here, including a button to show/hide the menu]
</Grid>
<Grid Grid.Column="1" x:Name="MenuGrid">
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="0*" />
<usercontrols:MyMenu Grid.Column="1" />
</Grid>
</Grid>
I've got my UserControl (MyMenu) currently hidden off the right side of the screen via ColumnDefintion setting, but I don't feel like that's a good way to do it.
Add to that the idea that my main content should have a Button that, when clicked, will cause the MyMenu UserControl to slide in (or out) of the screen.
I've noticed that I can't seem to animate GridLength properties (their Value properties are read-only), and I might be able to use a VisualStateManager to animate the Margin.Left of the MyMenu. But that doesn't seem like the right way to do it.
I'd greatly appreciate any guidance on how to approach this task.
Upvotes: 2
Views: 453
Reputation: 61359
You can definitely use the Visual State Manager to start a storyboard. However, when it comes to animating stuff across a screen, TranslateTransform
is far better suited than Margin
.
First, define the render transform on your control:
<usercontrols:MyMenu x:Name="MenuControl">
<usercontrols:MyMenu.RenderTransform>
<!-- Start off screen -->
<TranslateTransform X=-1000/>
</usercontrols:MyMenu.RenderTransform>
</usercontrols:MyMenu>
Then in your storyboard, target the X property of the transform. The path is a little tricky:
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MenuControl"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X) "
From="-1000"
To="0"
Duration="0:0:2"/>
</Storyboard>
Basically, you have to put the fact that the RenderTransform
is a TranslateTransform
as part of the property path.
Finally, run the storyboard however you like, the Visual State Manager is certainly reasonable.
Upvotes: 4
Reputation: 9
Not sure if this is what you want but if you want an easy way to do a slide effect when clicking on a button there's that :
Create a button "slide_menu", add to that a timer with enable proprety as false.
Resize your window menu to whatever size you want at the minimum(when its hidden) and put the maximum size(width or height) into the code, here its 300.
private void tm_Tick(object sender, EventArgs e) //the tick event of the timer
{
if (this.Height >= 300) // here is my windows that is 300 height when slided.
this.tm.Enabled = false; // disables the timer when max size is reached.
else
this.Height += 12; //choose a value that fits you. (the more you add to it, the faster it will slide to the reach maximum point"
}
private void slide_dwn_Click(object sender, EventArgs e)
{
this.tm.Enabled = true; //enables the timer when clicking on the button
}
You can also do it from an horizontal view, just change Height by Width in the code.
Also dont forget to change the interval of the timer to 1 for a smooth effect, you can find it in the propreties of the timer in the design form.
Hope this helped.
Upvotes: -1
Reputation: 31724
The properties you mention you'd like to animate are associated with layout updates which means each change requires layout calculations from other elements in the visual tree which can be slow when we're in a context of 20-60fps animation. That's why WinRT-XAML treats these differently and it requires marking an animation with the EnableDependentAnimation
tag to enable it. What you typically should do in such cases instead is apply a RenderTransform
to the element you'd like to slide, use a TranslateTransform
to do the actual translation and have the animation target the transform's X
or Y
property.
Upvotes: 2