Анимация загрузки элемента ListBox - PullRequest
7 голосов
/ 06 мая 2011

Я хочу создать пользовательский элемент управления на основе ListBox (ListView) с такой анимацией: элементы в списке не загружаются все сразу, они должны загружаться пошагово (поэлементно, сначала потом, потом вторым, затем третье и т. д.) с некоторым временем ожидания между ними.

Как я могу это сделать?

1 Ответ

10 голосов
/ 06 мая 2011

Для этого можно использовать поведение Blend SDK:

<ListBox ItemsSource="{Binding Collection, Source={StaticResource SampleData}}">
    <i:Interaction.Behaviors>
        <b:FadeAnimateItemsBehavior Tick="0:0:0.05">
            <b:FadeAnimateItemsBehavior.Animation>
                <DoubleAnimation From="0" To="1" Duration="0:0:0.3"/>
            </b:FadeAnimateItemsBehavior.Animation>
        </b:FadeAnimateItemsBehavior>
    </i:Interaction.Behaviors>
</ListBox>
class FadeAnimateItemsBehavior : Behavior<ListBox>
{
    public DoubleAnimation Animation { get; set; }
    public TimeSpan Tick { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += new System.Windows.RoutedEventHandler(AssociatedObject_Loaded);
    }

    void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        IEnumerable<ListBoxItem> items;
        if (AssociatedObject.ItemsSource == null)
        {
            items = AssociatedObject.Items.Cast<ListBoxItem>();
        }
        else
        {
            var itemsSource = AssociatedObject.ItemsSource;
            if (itemsSource is INotifyCollectionChanged)
            {
                var collection = itemsSource as INotifyCollectionChanged;
                collection.CollectionChanged += (s, cce) =>
                    {
                        if (cce.Action == NotifyCollectionChangedAction.Add)
                        {
                            var itemContainer = AssociatedObject.ItemContainerGenerator.ContainerFromItem(cce.NewItems[0]) as ListBoxItem;
                            itemContainer.BeginAnimation(ListBoxItem.OpacityProperty, Animation);
                        }
                    };

            }
            ListBoxItem[] itemsSub = new ListBoxItem[AssociatedObject.Items.Count];
            for (int i = 0; i < itemsSub.Length; i++)
            {
                itemsSub[i] = AssociatedObject.ItemContainerGenerator.ContainerFromIndex(i) as ListBoxItem;
            }
            items = itemsSub;
        }
        foreach (var item in items)
        {
            item.Opacity = 0;
        }
        var enumerator = items.GetEnumerator();
        if (enumerator.MoveNext())
        {
            DispatcherTimer timer = new DispatcherTimer() { Interval = Tick };
            timer.Tick += (s, timerE) =>
            {
                var item = enumerator.Current;
                item.BeginAnimation(ListBoxItem.OpacityProperty, Animation);
                if (!enumerator.MoveNext())
                {
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
}

Tick указывает время между моментом, когда элементы начинают исчезать. Animation - это анимация, применяемая к непрозрачности для появления, она может быть установлена ​​в Xaml как очень экономичная (например, функции ослабления и время исчезновения). ).

Редактировать: Добавлен новый элемент исчезновения (работает, только если используется ItemsSource и реализует INotifyCollectionChanged)

( Используйте фрагменты кода, подобные этому, с осторожностью, если вообще. Этот код предназначен в основном для демонстрационных целей и дает общее представление о том, как к этому можно приблизиться. Возможно, это также можно сделать с помощью встроенного в Blend 4 FluidMoveBehaviors если есть. )

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