我正在使用MVVM,绑定到ObservableCollection<Shape>
(DrawingInstructions),并希望为添加的Line
形状设置动画。
应按照DoubleAnimation
的方式从(X1,Y1)到(X2,Y2)绘制各条线。
我尝试过对以下内容进行变体,但都不起作用。
<ItemsControl ItemsSource="{Binding Path=DrawingInstructions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate >
<Canvas>
:
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Position" From="{Binding Path=X1}" To="{Binding Path=X2}"/>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Position" From="{Binding Path=Y1}" To="{Binding Path=Y2}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ItemsControl.Triggers>
视图模型包含命名要添加到图形说明中的直线的代码。
var line = new Line
{
X1 = currentSituation.Position.X,
Y1 = currentSituation.Position.Y,
X2 = newSituation.Position.X,
Y2 = newSituation.Position.Y,
Name = "CurrentLine",
Stroke = brush,
StrokeThickness = 2
};
drawingInstructions.Add(line);
更新:
@Nico提出的解决方案有效——引入一个"模型"类,表示具有X1
、X2
、Y1
、Y2
和TimeOffset
属性的Line
。使用动画中的各个属性将数据绑定到ObservableCollection<MyModelClass>
:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line Name="CurrentLine" X1="{Binding X1}" Y1="{Binding Y1}" X2="{Binding X1}" Y2="{Binding Y1}" Stroke="Black" StrokeThickness="2">
<Line.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="X2" BeginTime="{Binding Path=TimeOffset}" From="{Binding Path=X1}" To="{Binding Path=X2}"/>
<DoubleAnimation Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Y2" BeginTime="{Binding Path=TimeOffset}" From="{Binding Path=Y1}" To="{Binding Path=Y2}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Line.Triggers>
</Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
首先,不能将ItemsControl绑定到行的集合并将其显示为行。相反,您应该创建一个具有必要属性的模型类。否则,您将得到一个WPF错误。我使用这些类进行测试:
public class VM
{
public ObservableCollection<DrawingInstruction> DrawingInstructions { get; set; }
}
public class DrawingInstruction
{
public double X1 { get; set; }
public double X2 { get; set; }
public double Y1 { get; set; }
public double Y2 { get; set; }
}
然后,如前所述,您应该以动画中的X2和Y2特性为目标。以下是适用于我的XAML:
<ItemsControl ItemsSource="{Binding DrawingInstructions}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate >
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line Name="CurrentLine" X1="{Binding X1}" Y1="{Binding Y1}" Stroke="Black" StrokeThickness="2">
<Line.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="X2" From="{Binding Path=X1}" To="{Binding Path=X2}"/>
<DoubleAnimation Duration="0:0:2" Storyboard.TargetName="CurrentLine" Storyboard.TargetProperty="Y2" From="{Binding Path=Y1}" To="{Binding Path=Y2}"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Line.Triggers>
</Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
控件加载后,动画立即开始。我希望这是你的本意。因为每个项目都有自己的动画,所以应该将动画添加到ItemTemplate中。