¿Hay alguna manera de animar el ancho de la columna de cuadrícula o la altura de la cuadrícula desde XAML?¿Animar columna de cuadrícula o fila de cuadrícula en XAML?
Respuesta
Las propiedades ColumnDefinition.Width
y RowDefinition.Height
son del tipo GridLength
, y no hay animaciones incorporadas para este tipo. Entonces, si quieres hacer eso, probablemente tendrás que crear tu propia clase GridLengthAnimation
. Eso no es probablemente demasiado imposible si se toma DoubleAnimation
como un ejemplo, pero no es fácil, ya sea ...
EDIT: En realidad, hay varios resultados interesantes si se busca "animación GridLength" en Google ...
http://windowsclient.net/learn/video.aspx?v=70654
http://marlongrech.wordpress.com/2007/08/20/gridlength-animation/
http://www.codeproject.com/KB/WPF/GridLengthAnimation.aspx
me cansé de tener que jugar con XAML para animar filas y columnas de la cuadrícula hace un tiempo, así que escribió un par de métodos para hacerlo totalmente de código.
Con estos se puede ampliar/reducir el tamaño de columnas y filas de código con una línea:
Animation.AnimationHelper.AnimateGridColumnExpandCollapse(LeftColumn, true, expandedHeight, currentWidth, LeftColumn.MinWidth, 0, 200);
Una cosa importante a destacar es el establecimiento de la animación nula en la terminación. Si no lo hace, la cuadrícula aún está bajo control de la animación cuando se completa la animación. Esto podría estar bien si la cuadrícula no tiene un divisor, pero si la cuadrícula tiene un divisor y desea poder cambiar el tamaño manualmente después de que la animación se complete, entonces debe configurar la animación como nula después de que se complete.
Aquí son los métodos:
/// <summary>
/// Animate expand/collapse of a grid column.
/// </summary>
/// <param name="gridColumn">The grid column to expand/collapse.</param>
/// <param name="expandedWidth">The expanded width.</param>
/// <param name="milliseconds">The milliseconds component of the duration.</param>
/// <param name="collapsedWidth">The width when collapsed.</param>
/// <param name="minWidth">The minimum width of the column.</param>
/// <param name="seconds">The seconds component of the duration.</param>
/// <param name="expand">If true, expand, otherwise collapse.</param>
public static void AnimateGridColumnExpandCollapse(ColumnDefinition gridColumn, bool expand, double expandedWidth, double collapsedWidth,
double minWidth, int seconds, int milliseconds)
{
if(expand && gridColumn.ActualWidth >= expandedWidth)
// It's as wide as it needs to be.
return;
if (!expand && gridColumn.ActualWidth == collapsedWidth)
// It's already collapsed.
return;
Storyboard storyBoard = new Storyboard();
GridLengthAnimation animation = new GridLengthAnimation();
animation.From = new GridLength(gridColumn.ActualWidth);
animation.To = new GridLength(expand ? expandedWidth : collapsedWidth);
animation.Duration = new TimeSpan(0, 0, 0, seconds, milliseconds);
// Set delegate that will fire on completion.
animation.Completed += delegate
{
// Set the animation to null on completion. This allows the grid to be resized manually
gridColumn.BeginAnimation(ColumnDefinition.WidthProperty, null);
// Set the final value manually.
gridColumn.Width = new GridLength(expand ? expandedWidth : collapsedWidth);
// Set the minimum width.
gridColumn.MinWidth = minWidth;
};
storyBoard.Children.Add(animation);
Storyboard.SetTarget(animation, gridColumn);
Storyboard.SetTargetProperty(animation, new PropertyPath(ColumnDefinition.WidthProperty));
storyBoard.Children.Add(animation);
// Begin the animation.
storyBoard.Begin();
}
/// <summary>
/// Animate expand/collapse of a grid row.
/// </summary>
/// <param name="gridRow">The grid row to expand/collapse.</param>
/// <param name="expandedHeight">The expanded height.</param>
/// <param name="collapsedHeight">The collapesed height.</param>
/// <param name="minHeight">The minimum height.</param>
/// <param name="milliseconds">The milliseconds component of the duration.</param>
/// <param name="seconds">The seconds component of the duration.</param>
/// <param name="expand">If true, expand, otherwise collapse.</param>
public static void AnimateGridRowExpandCollapse(RowDefinition gridRow, bool expand, double expandedHeight, double collapsedHeight, double minHeight, int seconds, int milliseconds)
{
if (expand && gridRow.ActualHeight >= expandedHeight)
// It's as high as it needs to be.
return;
if (!expand && gridRow.ActualHeight == collapsedHeight)
// It's already collapsed.
return;
Storyboard storyBoard = new Storyboard();
GridLengthAnimation animation = new GridLengthAnimation();
animation.From = new GridLength(gridRow.ActualHeight);
animation.To = new GridLength(expand ? expandedHeight : collapsedHeight);
animation.Duration = new TimeSpan(0, 0, 0, seconds, milliseconds);
// Set delegate that will fire on completioon.
animation.Completed += delegate
{
// Set the animation to null on completion. This allows the grid to be resized manually
gridRow.BeginAnimation(RowDefinition.HeightProperty, null);
// Set the final height.
gridRow.Height = new GridLength(expand ? expandedHeight : collapsedHeight);
// Set the minimum height.
gridRow.MinHeight = minHeight;
};
storyBoard.Children.Add(animation);
Storyboard.SetTarget(animation, gridRow);
Storyboard.SetTargetProperty(animation, new PropertyPath(RowDefinition.HeightProperty));
storyBoard.Children.Add(animation);
// Begin the animation.
storyBoard.Begin();
}
I edificados sobre la clase AnimationHelper
proporcionada por Nigel Shaw y envolvió en una reutilizable GridAnimationBehavior
que se puede fijar a los elementos RowDefinition
y ColumnDefinition
.
/// <summary>
/// Wraps the functionality provided by the <see cref="AnimationHelper"/> class
/// in a behavior which can be used with the <see cref="ColumnDefinition"/>
/// and <see cref="RowDefinition"/> types.
/// </summary>
public class GridAnimationBehavior : DependencyObject
{
#region Attached IsExpanded DependencyProperty
/// <summary>
/// Register the "IsExpanded" attached property and the "OnIsExpanded" callback
/// </summary>
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.RegisterAttached("IsExpanded", typeof(bool), typeof(GridAnimationBehavior),
new FrameworkPropertyMetadata(OnIsExpandedChanged));
public static void SetIsExpanded(DependencyObject dependencyObject, bool value)
{
dependencyObject.SetValue(IsExpandedProperty, value);
}
#endregion
#region Attached Duration DependencyProperty
/// <summary>
/// Register the "Duration" attached property
/// </summary>
public static readonly DependencyProperty DurationProperty =
DependencyProperty.RegisterAttached("Duration", typeof(TimeSpan), typeof(GridAnimationBehavior),
new FrameworkPropertyMetadata(TimeSpan.FromMilliseconds(200)));
public static void SetDuration(DependencyObject dependencyObject, TimeSpan value)
{
dependencyObject.SetValue(DurationProperty, value);
}
private static TimeSpan GetDuration(DependencyObject dependencyObject)
{
return (TimeSpan)dependencyObject.GetValue(DurationProperty);
}
#endregion
#region GridCellSize DependencyProperty
/// <summary>
/// Use a private "GridCellSize" dependency property as a temporary backing
/// store for the last expanded grid cell size (row height or column width).
/// </summary>
private static readonly DependencyProperty GridCellSizeProperty =
DependencyProperty.Register("GridCellSize", typeof(double), typeof(GridAnimationBehavior),
new UIPropertyMetadata(0.0));
private static void SetGridCellSize(DependencyObject dependencyObject, double value)
{
dependencyObject.SetValue(GridCellSizeProperty, value);
}
private static double GetGridCellSize(DependencyObject dependencyObject)
{
return (double)dependencyObject.GetValue(GridCellSizeProperty);
}
#endregion
/// <summary>
/// Called when the attached <c>IsExpanded</c> property changed.
/// </summary>
private static void OnIsExpandedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var duration = GetDuration(dependencyObject);
var rowDefinition = dependencyObject as RowDefinition;
if (rowDefinition != null)
{
// The IsExpanded attached property of a RowDefinition changed
if ((bool)e.NewValue)
{
var expandedHeight = GetGridCellSize(rowDefinition);
if (expandedHeight > 0)
{
// Animate row height back to saved expanded height.
AnimationHelper.AnimateGridRowExpandCollapse(rowDefinition, true, expandedHeight, rowDefinition.ActualHeight, 0, duration);
}
}
else
{
// Save expanded height and animate row height down to zero.
SetGridCellSize(rowDefinition, rowDefinition.ActualHeight);
AnimationHelper.AnimateGridRowExpandCollapse(rowDefinition, false, rowDefinition.ActualHeight, 0, 0, duration);
}
}
var columnDefinition = dependencyObject as ColumnDefinition;
if (columnDefinition != null)
{
// The IsExpanded attached property of a ColumnDefinition changed
if ((bool)e.NewValue)
{
var expandedWidth = GetGridCellSize(columnDefinition);
if (expandedWidth > 0)
{
// Animate column width back to saved expanded width.
AnimationHelper.AnimateGridColumnExpandCollapse(columnDefinition, true, expandedWidth, columnDefinition.ActualWidth, 0, duration);
}
}
else
{
// Save expanded width and animate column width down to zero.
SetGridCellSize(columnDefinition, columnDefinition.ActualWidth);
AnimationHelper.AnimateGridColumnExpandCollapse(columnDefinition, false, columnDefinition.ActualWidth, 0, 0, duration);
}
}
}
}
Tenga en cuenta que pellizqué código de Nigel un poco para utilizar un parámetro de tipo periodo de tiempo para la duración de la animación en lugar de segundos separados y parámetros milisegundos.
Este comportamiento hace que la animación de filas/columnas de cuadrícula sea amigable con MVVM (solo XAML, no se requiere código). Ejemplo:
<Grid.RowDefinitions>
<RowDefinition Height="*" Behaviors:GridAnimationBehavior.IsExpanded="{Binding IsUpperPaneVisible}" />
<RowDefinition Height="*" />
<RowDefinition Height="*" Behaviors:GridAnimationBehavior.IsExpanded="{Binding IsLowerPaneVisible}" />
</Grid.RowDefinitions>
He añadido esta respuesta porque el cartel original solicitó una solución XAML pura.
¿Qué tal un trabajo? ¿Por qué no colocar una cuadrícula (o cualquier otro control deseado) dentro de la fila en particular que desea animar, establecer la altura de la fila en "Auto", luego animar la altura del control. Funcionó para mí
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button x:Name="ExpandCollapseBtn" Width="100" Click="ExpandCollapse_Click"/>
<WrapPanel x:Name="ToolBox" Grid.Row="1" Height="0">
<Button Content="1" Width="50" Height="50"/>
<Button Content="2" Width="50" Height="50"/>
<Button Content="3" Width="50" Height="50"/>
<Button Content="4" Width="50" Height="50"/>
</WrapPanel>
</Grid>
Código atrás:
private bool Expanded = false;
void ExpandCollapse_Click(object sender, RoutedEventArgs e)
{
if (Expanded)
{
var anim = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(0.3));
anim.Completed += (s, _) => Expanded = false;
ToolBox.BeginAnimation(ContentControl.HeightProperty, anim);
}
else
{
var anim = new DoubleAnimation(100, (Duration)TimeSpan.FromSeconds(0.3));
anim.Completed += (s, _) => Expanded = true;
ToolBox.BeginAnimation(ContentControl.HeightProperty, anim);
}
}
que admitir que no es lo que busca. Pero es una solución rápida (suponiendo, por supuesto, que en última instancia desee colocar el UIElement dentro de la cuadrícula animando la fila de la grilla). De manera similar, puede hacerlo para el ancho de columna.
este fue, de lejos, el enfoque más simple ... funcionó muy bien, la cantidad mínima de código/molestia. – AshbyEngineer
La biblioteca MahApps.Metro tiene un control incorporado para esto. La fuente se puede encontrar here.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" x:Name="HamburgerMenuColumn" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Storyboard x:Key="CloseMenu" Storyboard.TargetName="HamburgerMenuColumn" Storyboard.TargetProperty="(ColumnDefinition.Width)">
<metro:GridLengthAnimation To="48" Duration="00:00:00"></metro:GridLengthAnimation>
</Storyboard>
</Grid.Resources>
</Grid>
- 1. ¿Cómo desplazo una fila de cuadrícula en WPF/XAML?
- 2. Establecer columna cuadrícula/Ancho de fila/Altura dinámicamente
- 3. cuadrícula dentro de la red en XAML
- 4. WPF Ocultar columna de cuadrícula
- 5. JQGrid Programemente selecciona cuadrícula Fila
- 6. Cómo colocar un control de usuario XAML en una cuadrícula
- 7. ¿Cómo configuro una columna de cuadrícula/tamaño de fila sin definir cada línea?
- 8. Fila de cuadrícula de datos de Silverlight Haga clic en
- 9. Ocultar cuadrícula ExtJS Columna encabezado
- 10. Aplicar un color de fondo a una fila de cuadrícula completa en XAML Silverlight
- 11. Cuadrícula, cuadrícula flexible o diseño de grilla de cuadrícula para MFC
- 12. ¿Qué control de cuadrícula/cuadrícula en WPF?
- 13. Cuadrícula de datos en WPF - Prefijo de columna 1 ordenado
- 14. Columna ExtJS 4 "Renderer" en la cuadrícula
- 15. Cómo establecer las posiciones de fila y columna de la cuadrícula mediante programación
- 16. prevención de cambio de fila en la cuadrícula de datos
- 17. ¿Cómo seleccionar una fila en la cuadrícula DESPUÉS de cargar la cuadrícula?
- 18. alineación de celda de fila de cabecera de cuadrícula pulida
- 19. Cómo establecer el ancho máximo de la columna de cuadrícula según la ventana o el tamaño de pantalla en XAML
- 20. Recuento de fila y columna de la cuadrícula de datos en C#
- 21. ¿Cómo se inserta una fila/columna en una cuadrícula de WPF?
- 22. Cuadrícula de datos Establecer foco en la fila recién agregada
- 23. ¿Cómo acceder mediante programación a Control en cuadrícula WPF por índice de fila y columna?
- 24. Grupo de radio en ExtJS Editor Cuadrícula/Cuadrícula
- 25. ¿Cómo dividir una fila de cuadrícula en dos columnas?
- 26. SharedSizeGroup de cuadrícula y * dimensionamiento
- 27. Diseñar un fondo de cuadrícula de diseño WPF (de cada celda, fila, columna)
- 28. WPF Tamaño de la cuadrícula
- 29. Wpf: Cuadrícula: ¿Cómo puedo compartir el ancho de altura de columna/fila?
- 30. Cambiar fila de cuadrícula de datos WPF Color
El primer enlace me ayudó a asignarlo, gracias :) –
Annnd ... el enlace "windowsclient.net" está roto. Parece que MS está desmantelando cualquier cosa anterior a Win8, o aplicando Razor de Hanlon, simplemente no le importa. – codekaizen
El primer enlace fue [guardado por Wayback Machine] (http://web.archive.org/web/20111201124746/http://windowsclient.net/learn/video.aspx?v=70654) – fernio