Как я могу анимировать высоту ListView при добавлении элементов через ItemsSource? - PullRequest
0 голосов
/ 08 мая 2009

У меня есть ListView, который настроен с MinHeight и MaxHeight. Окончательная высота определяется количеством элементов в списке.

В тот момент, когда список добавляется в свойство ItemsSource объекта ListView, высота переходит к конечной высоте. Есть ли способ оживить это изменение высоты, чтобы оно было плавным?

1 Ответ

1 голос
/ 08 мая 2009

Вот пример чего-то, что делает то, что вы хотите (насколько я понимаю). Я назову это «быстрым и грязным» и не претендую на то, что вложил в это много мыслей.

    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 сверху моей головы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...