【问题标题】:ListBox item load animationListBox 项加载动画
【发布时间】:2011-05-06 10:43:08
【问题描述】:

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

我该怎么做?

【问题讨论】:

    标签: wpf listview animation listbox


    【解决方案1】:

    您可以为此使用 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 是应用于 Opacity 以进行淡入的动画,它可以在 Xaml 中设置为非常可定制(例如缓动函数和淡入时间)。

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

    (如果有的话,请谨慎使用这样的代码 sn-ps。这段代码主要用于演示目的,并给出如何处理这个问题的一般概念。这也可以使用 Blend 4 的本机来完成FluidMoveBehaviors 如果有的话。)

    【讨论】:

    • 感谢您提供如此合格的回答!最后,我怎么能在没有 Opacity 属性但具有 Visibility 属性的情况下为项目设置动画。我尝试了很多,但做不到。
    • 您可以使用ObjectAnimationUsingKeyFrames 为可见性设置动画,在this answer 中您可以看到一个示例。
    • 谢谢!因为这样的动画(或行为)没有特殊的名称(手风琴?-可能是最好的!),所以试图找到答案。
    • 很高兴它有帮助。如果这回答了您的问题,您可以通过单击我的答案左侧的复选标记大纲来接受它。
    • 如何将它用于充满形状的画布?
    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多