【问题标题】:How could I animate one stack panel item at a time?如何一次为一个堆栈面板项设置动画?
【发布时间】:2010-12-03 00:31:49
【问题描述】:

假设我有一个 StackPanel,里面有一些项目。当我加载视图时,我想对它们应用一些动画。但我希望每个项目按顺序动画,一个接一个。我该怎么做呢?特别是,在 MVVM 框架中是否有一种干净的方法可以做到这一点?

编辑 - 我应该提到,这些项目是通过 ItemsControl 数据绑定到 StackPanel 的,这可能会使事情变得更加困难。看起来是这样的

                   <ItemsControl x:Name="Items">
                        <ItemsControl.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel />
                            </ItemsPanelTemplate>
                        </ItemsControl.ItemsPanel>
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <Button Content="{Binding ButtonName}"/>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>

为清楚起见,省略了一些 UI 代码。

【问题讨论】:

    标签: c# wpf silverlight xaml animation


    【解决方案1】:

    复制/粘贴/编译/运行:我会给出解释,但要涵盖的主题太多。基本上,该示例展示了如何在不冻结 UI 的情况下在后台进行 MultiTrigger、动画、加载项目以及使用 PropertyChanged 通知 UI。 享受吧。

    这是 XAML

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="MainWindow" Height="350" Width="525"
        x:Name="wnd">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisibility" />
    </Window.Resources>
    
    <ItemsControl x:Name="Items" ItemsSource="{Binding TestItems, ElementName=wnd}" Loaded="Items_Loaded">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button x:Name="item" Content="{Binding DisplayString}" Margin="5">
                    <Button.Style>
                        <Style TargetType="{x:Type Button}">
                            <Setter Property="Opacity" Value="0"/>
                            <Setter Property="Visibility" Value="{Binding Path=IsVisible, Converter={StaticResource BoolToVisibility}}"/>
                            <Style.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding IsLoading}" Value="True"/>
                                        <Condition Binding="{Binding IsVisible}" Value="True"/>
                                    </MultiDataTrigger.Conditions>
                                    <MultiDataTrigger.EnterActions>
                                        <BeginStoryboard>
                                            <Storyboard >
                                                <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:1.5" AccelerationRatio="0.3"/>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </MultiDataTrigger.EnterActions>
                                </MultiDataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>                   
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    下面是它背后的代码:

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Globalization;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows;
    
    namespace WpfApplication1
    {
    
    public partial class MainWindow : Window
    {
        private List<TestItem> _items;
        public List<TestItem> TestItems
        {
            get
            {
                if(_items == null)
                {
                    _items = new List<TestItem>();
                    for(int i = 0; i < 10; i++)
                        _items.Add(new TestItem{ DisplayString = i.ToString(CultureInfo.InvariantCulture), IsVisible = true});
                }
                    return _items;
            }
        }
    
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void Items_Loaded(object sender, RoutedEventArgs e)
        {
            /*in background so not to freeze the UI thread*/
            Task.Factory
                .StartNew(() =>
                            {
                                foreach (var item in TestItems)
                                {
                                    item.IsLoading = true;
                                    item.IsVisible = true;
                                    /*using sleep as quick and dirty just to slow down loading and show the animation (otherwise it's a no-no )*/
                                    Thread.Sleep(500);
                                }
                            }
                );
        }
    }
    
    public class TestItem : INotifyPropertyChanged
    {
        private string _displayString;
        private bool _isVisible;
        private bool _isLoading;
    
        public string DisplayString
        {
            get { return _displayString; } 
            set
            {
                if (_displayString == value) return;
                _displayString = value;
                RaisePropertyChanged("DisplayString");
            }
        }
    
        public bool IsVisible
        {
            get { return _isVisible; }
            set
            {
                if (_isVisible == value) return;
                _isVisible = value;
                RaisePropertyChanged("IsVisible");
            }
        }
    
        public bool IsLoading
        {
            get { return _isLoading; }
            set
            {
                if (_isLoading == value) return;
                _isLoading = value;
                RaisePropertyChanged("IsLoading");
            }
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void RaisePropertyChanged(string propertyName)
        {
            if(PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多