Esiste un modo per animare la larghezza della colonna Grid o l'altezza della riga della griglia da XAML?Animazione della griglia o della griglia in XAML?
risposta
Le proprietà ColumnDefinition.Width
e RowDefinition.Height
sono di tipo GridLength
e non sono presenti animazioni incorporate per questo tipo. Quindi, se vuoi farlo, probabilmente dovrai creare la tua classe GridLengthAnimation
. Questo non è probabilmente troppo impossibile se si prende DoubleAnimation
come esempio, ma non è facile o ...
EDIT: in realtà, ci sono diversi risultati interessanti se si cerca "l'animazione GridLength" su 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
mi sono stancato di dover armeggiare con XAML per animare le righe e le colonne della griglia qualche tempo fa così ho scritto un paio di metodi per farlo totalmente dal codice.
Con questi è possibile espandere/shrink colonne e righe da codice con una sola riga:
Animation.AnimationHelper.AnimateGridColumnExpandCollapse(LeftColumn, true, expandedHeight, currentWidth, LeftColumn.MinWidth, 0, 200);
Una cosa importante da notare è l'impostazione l'animazione per nulla al termine. Se non lo fai, la griglia è ancora sotto controllo dell'animazione quando l'animazione è completa. Questo potrebbe andare bene se la griglia non ha uno splitter, ma se la griglia ha uno splitter e vuoi essere in grado di ridimensionarlo manualmente dopo il completamento dell'animazione, devi impostare l'animazione su null dopo il completamento.
Questi sono i metodi:
/// <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();
}
ho costruito dalla classe AnimationHelper
fornito da Nigel Shaw e avvolto in un riutilizzabile GridAnimationBehavior
associabile agli elementi RowDefinition
e 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);
}
}
}
}
noti che ho ottimizzato il codice di Nigel un po 'di utilizzare un parametro di tipo TimeSpan per la durata animazione anziché secondi separati e parametri millisecondi.
Questo comportamento rende l'animazione delle righe/colonne della griglia MVVM amichevole (solo XAML, nessun codice dietro richiesto). Esempio:
<Grid.RowDefinitions>
<RowDefinition Height="*" Behaviors:GridAnimationBehavior.IsExpanded="{Binding IsUpperPaneVisible}" />
<RowDefinition Height="*" />
<RowDefinition Height="*" Behaviors:GridAnimationBehavior.IsExpanded="{Binding IsLowerPaneVisible}" />
</Grid.RowDefinitions>
Ho aggiunto questa risposta perché il poster originale richiedeva una soluzione XAML pura.
Che ne dici di un lavoro in giro? Perché non posizionare una griglia (o qualsiasi altro controllo desiderato) all'interno della particolare riga che si desidera animare, impostare l'altezza della riga su "Auto", quindi animare l'altezza del controllo. Ha funzionato per me.
<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>
codice dietro:
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);
}
}
ammetto la sua non è quello che stai cercando. Ma è una soluzione rapida (supponendo che alla fine si desideri che l'UIElement sia inserito nella griglia animato animando la riga della griglia). Puoi farlo allo stesso modo per la larghezza della colonna.
questo era di gran lunga l'approccio più semplice ... ha funzionato molto bene, meno quantità di codice/seccature. – AshbyEngineer
La libreria MahApps.Metro dispone di un controllo incorporato per questo. La fonte può essere trovata 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. griglia all'interno Griglia in XAML
- 2. Come allungare il rettangolo sulla cella della griglia in XAML
- 3. Come si scorre una riga della griglia in WPF/XAML?
- 4. Rilevamento della griglia in MATLAB
- 5. Unisci colonne della griglia
- 6. Magento posizione della colonna della griglia
- 7. L'altezza della griglia viene tagliata
- 8. KendoUI: impostazione della griglia in ordine programmato
- 9. Cambiare comportamento linea della griglia in ggplot2
- 10. Aumentare la spaziatura della griglia in Android
- 11. Evento di modifica della selezione della riga della griglia Kendo?
- 12. Evidenziazione/selezione della riga della griglia in ExtJS
- 13. Come formattare un valore numerico nella cella della griglia della griglia AngularJS a due decimali?
- 14. come eliminare o aggiungere colonna nel pannello della griglia
- 15. Aggiorna una singola riga della griglia Kendo
- 16. Come impedire l'ordinamento della vista griglia dati
- 17. Perché la larghezza della mia griglia NaN?
- 18. Impostazione della larghezza della colonna nella griglia ui angolare
- 19. Layout griglia, retino flessibile o griglia per MFC
- 20. jQPlot - rimuove le linee verticali della griglia
- 21. Solo linee della griglia minori sull'asse x
- 22. rimozione griglia JTable (bordo della cella) completamente
- 23. Impaginazione del server della griglia KendoUI
- 24. Modifica della visibilità delle colonne della griglia utente angolare
- 25. Elemento della griglia di proprietà e DoubleClick
- 26. Binding EntranceThemeTransition Proprietà della griglia in MapItemsControl.ItemTemplate che non funziona
- 27. AngularJS ngAllineamento del testo della griglia
- 28. Chart.js v2 - nascondere le linee della griglia
- 29. Applicazione di un colore di sfondo a un'intera riga della griglia in XAML Silverlight
- 30. Ridimensionamento automatico della griglia al ridimensionamento della finestra
Il primo collegamento mi ha aiutato ad assegnare, grazie :) –
Annnd ... il collegamento "windowsclient.net" è rotto. Sembra che la SM stia smantellando qualsiasi cosa pre-Win8, o applicando il rasoio di Hanlon, semplicemente non se ne preoccupa. – codekaizen
Il primo collegamento è stato [salvato dalla Wayback Machine] (http://web.archive.org/web/20111201124746/http://windowsclient.net/learn/video.aspx?v=70654) – fernio