У меня есть 2 столбца в сетке. Когда я нажимаю кнопку, я хочу, чтобы первый столбец анимировался влево от его текущей позиции до 0. Таким образом, он сворачивается, и мне остается только просматривать один столбец.
В WPF кто-нибудь анимировал сетку?
Ответы (6)
Ознакомьтесь с этой ссылкой на обучающее видео от Тодда Миранды, в котором показано, как анимировать высота элемента управления сеткой. Я думаю, вы могли бы легко заставить его работать для вашего случая.
Не должно быть слишком сложно. Вам нужно будет создать EventTrigger с BeginStoryboard, который нацелен на сетку и использует DoubleAnimation для уменьшения ширины столбца. Пример здесь имеет аналогичную настройку. EventTrigger сработает на кнопке, а StoryBoard.Target будет указывать на ColumnDefinition, который вы хотите уменьшить.
Хорошо, так что это не работает так хорошо. Вы не можете сжать столбец напрямую, но вы МОЖЕТЕ установить для сжимающегося столбца заполнение (width="*"), установить ширину сетки и столбца без сокращения, а затем сжать всю сетку. Это работает. Пример ниже работает:
<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>
Вам необходимо создать класс GridLengthAnimation (код из: 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);
}
}
}
И раскадровка для 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>
Еще одна вещь, которую вы можете сделать, это анимировать содержимое и настроить сетку на автоматический размер содержимого, что будет происходить плавно при изменении размера содержимого.
Вы также можете добиться этого с помощью анимации GridLength, см. пример здесь http://marlongrech.wordpress.com/2007/08/20/gridlength-animation/ Используя этот подход, вы можете управлять любым заданным размером Grid.Column или Grid.Row.
Для ваших особых нужд просто поместите первый столбец с Width="Auto" и второй с *, анимируйте содержимое внутри первого столбца - это сделает свое дело.
Я взял исходный код C# Тодда Миранды и изменил его, чтобы продемонстрировать, как анимировать уменьшение и расширение ширины столбцов DataGrid.
Вот исходный код...
http://www.pocketpctoolkit.com/WPF/DataGridColumnWidthAnimation.zip
По сути, вы нажимаете на CheckBox, и любые столбцы DataGrid, для которых значение «MinWidth» установлено равным 0, будут сжаты до нулевой ширины. Нажмите CheckBox еще раз, столбцы вернутся к своей исходной ширине.
Этот код WPF также демонстрирует, как создавать анимации/раскадровки в коде позади.