In WPF, has anybody animated a Grid?

青春壹個敷衍的年華 提交于 2019-11-28 11:54:46

Check out this video training link, from Todd Miranda that shows you how to animate the height of a grid control. I think you could easily make it work for your case.

Will

Shouldn't be too hard. You'd need to create an EventTrigger that has a BeginStoryboard that targets the grid and uses a DoubleAnimation to shrink the column width. The example here has a similar setup. The EventTrigger would go on the button and the DoubleAnimation's StoryBoard.Target would point to the ColumnDefinition you wish to shrink.

Okay, so that doesn't work so well. You can't shrink the column directly, but you CAN set the shrinking column to fill (width="*"), set the width of the Grid and the non-shrinking column, and then shrink the entire grid. This does work. The below example works:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      WindowTitle="Opacity Animation Example" 
      Background="White">
   <StackPanel Margin="20">
      <Grid Name="MyGrid" Width="200" HorizontalAlignment="Left">
         <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
         </Grid.RowDefinitions>
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="100"/>
         </Grid.ColumnDefinitions>
         <Rectangle HorizontalAlignment="Stretch"  
                    VerticalAlignment="Stretch" 
                    Grid.Column="0" Fill="Red"/>
         <Rectangle HorizontalAlignment="Stretch"  
                    VerticalAlignment="Stretch" 
                    Grid.Column="1" Fill="Blue"/>
      </Grid>

      <Button Name="hideButton">
         <Button.Triggers>
            <EventTrigger RoutedEvent="Button.Click">
               <BeginStoryboard>
                  <Storyboard>
                     <DoubleAnimation 
                         Storyboard.TargetName="MyGrid"
                         Storyboard.TargetProperty="(Grid.Width)" 
                         From="200" To="100" 
                         Duration="0:0:2" 
                         AutoReverse="True"  /> 
                  </Storyboard>
               </BeginStoryboard>
            </EventTrigger>
         </Button.Triggers>
      </Button>
   </StackPanel>
</Page>

You need to Create a GridLengthAnimation class (code from: http://windowsclient.net/learn/video.aspx?v=70654)

public class GridLengthAnimation : AnimationTimeline
{
    public GridLengthAnimation()
    {
        // no-op
    }

    public GridLength From
    {
        get { return (GridLength)GetValue(FromProperty); }
        set { SetValue(FromProperty, value); }
    }

    public static readonly DependencyProperty FromProperty =
      DependencyProperty.Register("From", typeof(GridLength), typeof(GridLengthAnimation));

    public GridLength To
    {
        get { return (GridLength)GetValue(ToProperty); }
        set { SetValue(ToProperty, value); }
    }

    public static readonly DependencyProperty ToProperty =
        DependencyProperty.Register("To", typeof(GridLength), typeof(GridLengthAnimation));

    public override Type TargetPropertyType
    {
        get { return typeof(GridLength); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new GridLengthAnimation();
    }

    public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
    {
        double fromValue = this.From.Value;
        double toValue = this.To.Value;

        if (fromValue > toValue)
        {
            return new GridLength((1 - animationClock.CurrentProgress.Value) * (fromValue - toValue) + toValue, this.To.IsStar ? GridUnitType.Star : GridUnitType.Pixel);
        }
        else
        {
            return new GridLength((animationClock.CurrentProgress.Value) * (toValue - fromValue) + fromValue, this.To.IsStar ? GridUnitType.Star : GridUnitType.Pixel);
        }
    }
}

And a Storyboard for the RowDefinition/ColumnDefinition.

<Window.Resources>
    <Storyboard x:Key="ColumnAnimation">
        <Animations:GridLengthAnimation
            BeginTime="0:0:0"
            Duration="0:0:0.1"
            From="0*"
            Storyboard.TargetName="ColumnToAnimate"
            Storyboard.TargetProperty="Width"
            To="10*" />
    </Storyboard>

</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="10*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition x:Name="ColumnToAnimate" Width="0*" />
    </Grid.ColumnDefinitions>
</Grid>

Another thing you can do is animate the contents and set the Grid to autosize to content which it will do smoothly as the contents changes size.

You can also use the Reveal control from Kevin's bag-o-tricks, http://j832.com/bagotricks/

You can also achieve this with GridLength animation , see an example here http://marlongrech.wordpress.com/2007/08/20/gridlength-animation/ Using this approach you can manipulate any given Grid.Column or Grid.Row size.

For your special need just put first column with Width="Auto" and second with *, animate the with of the content inside the first column- that will do the trick.

I have taken Todd Miranda's C# source code and modified it, to demonstrate how to animate DataGrid Column widths shrinking & expanding.

Here's the source code...

http://www.pocketpctoolkit.com/WPF/DataGridColumnWidthAnimation.zip

Basically, you click on a CheckBox, and whichever DataGrid columns have their "MinWidth" value set to 0 will be shrunk to zero-width. Click the CheckBox again, the columns will animate back to their original widths.

This WPF code also demonstrates how to create animations / storyboards in code behind.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!