I'm trying to write a basic proof-of-concept for having a grid layout, with two columns with content in them, plus a third column that has only a GridSplitter. The content in the left-most column will be resized by the GridSplitter, but I'd also like to have some collapse and expand buttons that shrink/grow this same column. Basically like the Solu开发者_如何学Pythontion Explorer in visual studio, which can be dragged bigger, or just unpinned, which collapses it.
The code is below. LeftPanel is what I'm trying to animate. If I set a Width on LeftPanel, it animates, but no longer automatically re-sizes to fill the grid column when I drag the GridSplitter around. And when I leave off Width from LeftPanel, or set it to Auto, it animates, but no longer resizes with the GridSplitter.
I looked at this post about adding a DependencyProperty to animate the GridColumn directly, but again, dragging the GridSplitter would break it.
<UserControl.Resources>
<Storyboard x:Key="animShrink" x:Name="sbShrink">
<DoubleAnimation Storyboard.TargetName="leftPanel" Storyboard.TargetProperty="Width" To="50" Duration="0:0:2" />
</Storyboard>
<Storyboard x:Key="animGrow" x:Name="sbGrow">
<DoubleAnimation Storyboard.TargetName="leftPanel" Storyboard.TargetProperty="Width" To="200" Duration="0:0:2" />
</Storyboard>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftGridCol" Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Width="Auto" Margin="0,0,10,0" Background="Bisque" x:Name="leftPanel" >
<Button x:Name="btnShrink" Click="Button_Shrink" Height="20" VerticalAlignment="Top">Shrink</Button>
<Button x:Name="btnGrow" Click="Button_Grow" Height="20" Margin="0,30,0,0" VerticalAlignment="Top">Grow</Button>
</StackPanel>
<sdk:GridSplitter Grid.Column="0"></sdk:GridSplitter>
<StackPanel Grid.Column="2" Background="AliceBlue"></StackPanel>
</Grid>
Handlers
private void Button_Grow(object sender, RoutedEventArgs e) {
sbGrow.Begin();
}
private void Button_Shrink(object sender, RoutedEventArgs e) {
sbShrink.Begin();
}
Here's the best answer I could come up with. If anyone has a better one, then please let me know.
First, take the width off leftPanel, then bind to your own DependencyProperty, as explained in the link above:
public double LeftGridWidth {
get { return (double)GetValue(LeftGridWidthProperty); }
set { SetValue(LeftGridWidthProperty, value); }
}
public static readonly DependencyProperty LeftGridWidthProperty =
DependencyProperty.Register("LeftGridWidth", typeof(double), typeof(MainPage), new System.Windows.PropertyMetadata(new PropertyChangedCallback(ColumnWidthChanged)));
private static void ColumnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){
(d as MainPage).leftGridCol.Width = new GridLength((double)e.NewValue);
}
Then, in order to get the gridSplitter to not screw things up, manually adjust your dependency property as needed:
private void leftPanel_SizeChanged(object sender, SizeChangedEventArgs e) {
LeftGridWidth = leftGridCol.Width.Value;
}
(note, you have to set an initial width on the grid column for this to work. Setting the grid column to Auto will mess this up, since the width comes through as 1, messing up the initial layout.
You can use can you use ObjectAnimationUsingKeyFrames to directly animate width (GridLength) in column definitions like this:
<Storyboard x:Name="StoryboardLogin">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Width)" Storyboard.TargetName="LeftColumn">
<DiscreteObjectKeyFrame KeyTime="0" Value="0"/>
<DiscreteObjectKeyFrame KeyTime="0:0:0.20" Value="Auto"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="LeftColumn" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
Not smooth unless you add more keyframes, but simple.
精彩评论