ListBox 项加载动画 [英] ListBox item load animation
问题描述
我想用这样的动画创建基于 ListBox (ListView) 的用户控件:listbox 中的项目不会一次全部加载,它们必须逐步加载(逐项,首先然后第二,然后是第三个,等等),它们之间有一些超时.
I want to create user control based on ListBox (ListView) with such animation: the items in listbox do not loads all at once, they have to load step-by-step (item-by-item, first then second, then third, etc.) with some timeout between them.
我该怎么做?
推荐答案
您可以为此使用 Blend SDK 行为:
You could use a Blend SDK behavior for this:
<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
是应用于 Opacity 以进行淡入的动画,可以在 Xaml 中设置为非常可定制(例如缓动功能和淡入淡出时间).
Tick
specifies the time between when items are started to fade in. Animation
is the animation applied to the Opacity for the fade in, it can be set in Xaml to be very costomizable (e.g. easing functions and fade time).
添加新项目淡入(仅在使用 ItemsSource 并实现 INotifyCollectionChanged
时有效)
Added new item fade in (only works if ItemsSource is used and implements INotifyCollectionChanged
)
(如果有的话,请谨慎使用这样的代码片段.这段代码主要用于演示目的,并给出如何处理这个问题的一般概念.这也可以使用 Blend 4 的原生 FluidMoveBehaviors
如果可用.)
(Use code snippets like this with caution, if at all. This code is mainly for demonstration purposes and giving a general idea of how this can be approached. This could probably also be done using Blend 4's native FluidMoveBehaviors
if availabe.)
这篇关于ListBox 项加载动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!