Wpf 列表框项目加载动画

Wpf 列表框项目加载动画,wpf,listview,animation,listbox,Wpf,Listview,Animation,Listbox,我想创建一个基于ListBox(ListView)的用户控件,并带有这样的动画:ListBox中的项目不会一次全部加载,它们必须一步一步地加载(项目一步,先加载后加载,然后加载第二个,然后加载第三个,等等),其间有一些超时 我如何才能做到这一点?您可以使用Blend SDK行为来实现这一点: <ListBox ItemsSource="{Binding Collection, Source={StaticResource SampleData}}"> <i:Intera

我想创建一个基于ListBox(ListView)的用户控件,并带有这样的动画:ListBox中的项目不会一次全部加载,它们必须一步一步地加载(项目一步,先加载后加载,然后加载第二个,然后加载第三个,等等),其间有一些超时


我如何才能做到这一点?

您可以使用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>

类FadeAnimateItemsBehavior:行为
{
公共双动画动画{get;set;}
公共时间间隔{get;set;}
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.Loaded+=新系统.Windows.RoutedEventHandler(AssociatedObject\u Loaded);
}
已加载无效关联对象(对象发送方,System.Windows.RoutedEventArgs e)
{
i数不清的项目;
if(AssociatedObject.ItemsSource==null)
{
items=AssociatedObject.items.Cast();
}
其他的
{
var itemsSource=AssociatedObject.itemsSource;
如果(itemsSource是INotifyCollectionChanged)
{
var collection=itemsSource作为INotifyCollectionChanged;
collection.CollectionChanged+=(s,cce)=>
{
if(cce.Action==NotifyCollectionChangedAction.Add)
{
var itemContainer=AssociatedObject.ItemContainerGenerator.ContainerFromItem(cce.NewItems[0])作为ListBoxItem;
itemContainer.BeginAnimation(ListBoxItem.OpacityProperty,动画);
}
};
}
ListBoxItem[]itemsSub=新ListBoxItem[AssociatedObject.Items.Count];
对于(int i=0;i
{
变量项=枚举数。当前;
item.BeginAnimation(ListBoxItem.OpacityProperty,动画);
如果(!enumerator.MoveNext())
{
timer.Stop();
}
};
timer.Start();
}
}
}
勾选
指定项目开始淡入的时间间隔<代码>动画是应用于淡入不透明度的动画,它可以在Xaml中设置为非常可压缩(例如,缓和功能和淡入时间)

编辑:添加了新项目淡入(仅当使用了ItemsSource并实现了
INotifyCollectionChanged
时才有效)


(如果有的话,请谨慎使用类似的代码片段。此代码主要用于演示目的,并给出了如何处理此问题的一般思路。这也可以使用Blend 4的原生
FluidMoveBehaviors
(如果可用)来完成。)

感谢您提供了这样的限定答案!最后,我如何在没有不透明属性但具有可见性属性的情况下设置项目的动画。我试了很多,但都做不到。你可以用一个动画,你可以看到一个例子。谢谢!因为这样的动画(或行为)并没有特别的名字(手风琴?——可能是最好的!),所以我们试图找到答案。很高兴它有帮助。如果这回答了你的问题,你可以通过点击我答案左边的复选框来接受它。我如何将它用于充满形状的画布?
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();
        }
    }
}