我想创建一个基于ListBox(或ListView)的用户控件,并带有以下动画效果:列表框中的项不会一次性全部加载,它们必须逐步加载(逐个项目,先第一个,然后第二个,第三个等等),并在它们之间设置一些延迟时间。
我该如何实现这个功能?
我该如何实现这个功能?
<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中设置以实现高度自定义(例如缓动函数和淡入时间)。
编辑:添加了新的项目淡入效果(仅在使用INotifyCollectionChanged
的ItemsSource
中有效)
(请谨慎使用此类代码段,如果使用的话。这段代码主要是为了演示目的,并给出如何处理这个问题的一般想法。如果可用,这也可能使用Blend 4的本机FluidMoveBehaviors
完成。)
ObjectAnimationUsingKeyFrames
来实现可见性动画效果,在 这个答案 中有一个示例。 - H.B.ItemsControl
并将其ItemsPanel
设置为Canvas
,然后绑定ItemsSource
并对其应用此行为(需要更改行为目标类型)。 - H.B.