通过ItemsSource添加项目时,如何设置ListView的高度动画?

时间:2009-05-07 23:26:43

标签: wpf listview animation

我有一个使用MinHeight和MaxHeight设置的ListView。最终高度由列表中的项目数决定。

目前,当列表添加到ListView的ItemsSource属性时,高度会跳转到最终高度。有没有办法对这个高度变化进行动画处理,以便它变得平滑?

1 个答案:

答案 0 :(得分:1)

这是一个做你想做的事情的例子(据我所知)。我会称之为“快速而肮脏”,并没有声称已经考虑了很多。

    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中的值,我就可以通过更改该值来触发动画(因为我不知道根据对顶部的ListView ItemsSource的更改来触发动画的简单方法我的头脑。)