Вот пример чего-то, что делает то, что вы хотите (насколько я понимаю). Я назову это «быстрым и грязным» и не претендую на то, что вложил в это много мыслей.
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();
}
}
ОБНОВЛЕНИЕ: Вы должны быть в состоянии скопировать это в файлы .cs и .xaml и запустить его в качестве примера приложения. Подводя итог, что я делаю: Установите для свойства MaxHeight что-то искусственно низкое, в моем случае я просто установил для него то же значение, что и для MinHeight. Затем вы можете создать раскадровку, которая оживит MaxHeight до его реального значения, что даст вам эффект плавного перехода. Хитрость заключается в том, чтобы указать, когда начинать анимацию. Я использую свойство зависимостей в подклассе ListView только потому, что это кажется самым простым вариантом для реализации в спешке. Мне просто нужно связать свойство зависимостей со значением в моей ViewModel, и я могу запустить анимацию, изменив это значение (поскольку я не знаю простого способа запуска анимации на основе изменения ListS ItemsSource сверху моей головы).