gpt4 book ai didi

c# - 我如何一次为一个堆栈面板项目制作动画?

转载 作者:太空宇宙 更新时间:2023-11-03 14:24:56 26 4
gpt4 key购买 nike

假设我有一个包含一些项目的 StackPanel。当我加载我的 View 时,我想对它们应用一些动画。但我希望每个项目都按顺序进行动画处理,一个接一个。我该怎么做呢?特别是,是否有一种干净的方法可以在 MVVM 框架中执行此操作?

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

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

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

最佳答案

复制/粘贴/编译/运行:我会给出一个解释,但主题太多无法涵盖。基本上,该示例展示了如何在不卡住 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));
}
}
}

关于c# - 我如何一次为一个堆栈面板项目制作动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4341431/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com