J'ai un ListView qui est mis en place avec un MinHeight et un MaxHeight. La hauteur finale est déterminée par le nombre d'éléments dans la liste. À l'heure actuelle, lorsqu'une liste est ajoutée à la propriété ItemsSource de ListView, la hauteur saute à la hauteur finale. Existe-t-il un moyen d'animer ce changement de hauteur, pour qu'il soit lisse?Comment puis-je animer la hauteur d'un ListView lors de l'ajout d'éléments via ItemsSource?
Répondre
Voici un exemple de quelque chose qui fait ce que vous voulez (si je comprends bien). Je vais appeler cela «rapide et sale» et ne prétends pas y avoir beaucoup réfléchi.
public class CustomListView : ListView
{
public bool IsAttached
{
get { return (bool)GetValue(IsAttachedProperty); }
set { SetValue(IsAttachedProperty, value); }
}
// Using a DependencyProperty as the backing store for IsAttached.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsAttachedProperty =
DependencyProperty.Register("IsAttached",
typeof(bool),
typeof(CustomListView),
new UIPropertyMetadata(false));
}
public class ViewModel : INotifyPropertyChanged
{
public void PopulateItems()
{
Items = new List<string>();
for (var i = 0; i < 200; i++)
{
Items.Add("The quick brown fox jumps over the lazy dog.");
}
InvokePropertyChanged(new PropertyChangedEventArgs("Items"));
IsAttached = true;
InvokePropertyChanged(new PropertyChangedEventArgs("IsAttached"));
}
public List<string> Items { get; private set; }
public bool IsAttached { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
private void InvokePropertyChanged(PropertyChangedEventArgs e)
{
var changed = PropertyChanged;
if (changed != null)
{
changed(this, e);
}
}
}
<Window x:Class="AnimateHeight.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AnimateHeight"
Title="Window1" Height="300" Width="300">
<StackPanel>
<Button Width="100" Content="Add Items" Click="OnClickAddItems"/>
<local:CustomListView x:Name="VariableListView" ItemsSource="{Binding Items}" IsAttached="{Binding IsAttached}" >
<local:CustomListView.Style>
<Style TargetType="{x:Type local:CustomListView}">
<Setter Property="MinHeight" Value="50" />
<Setter Property="MaxHeight" Value="50" />
<Style.Triggers>
<Trigger Property="IsAttached" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(ListView.MaxHeight)"
To="150"
Duration="0:0:5"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</local:CustomListView.Style>
</local:CustomListView>
</StackPanel>
</Window>
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new ViewModel();
}
private void OnClickAddItems(object sender, RoutedEventArgs e)
{
((ViewModel)DataContext).PopulateItems();
}
}
MISE À JOUR: Vous devriez être en mesure de copier ceci dans .cs et les fichiers XAML et l'exécuter comme un exemple d'application. Pour récapituler ce que je fais: Réglez la propriété MaxHeight à quelque chose de artificiellement bas, dans mon cas je l'ai juste mis à la même valeur que le MinHeight. Ensuite, vous pouvez créer un storyboard qui anime le MaxHeight à sa valeur réelle, ce qui vous donne l'effet de transition en douceur. L'astuce indique quand démarrer l'animation, j'utilise une propriété de dépendance dans un ListView sous-classé juste parce que cela semble être l'option la plus facile à implémenter rapidement. Je dois juste lier la propriété de dépendance à une valeur dans mon ViewModel et je peux déclencher l'animation en changeant cette valeur (puisque je ne connais pas un moyen facile de déclencher une animation basée sur une modification d'un ListView ItemsSource du haut de ma tête).