1

我正在尝试使用 WPF 制作简单的动画。我有使用ItemTemplateSelector绘制球的画布。

 <ItemsControl ItemsSource="{Binding Path=Cells}" Name="ItemsControlCells">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas Width="450" Height="450">
                    </Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplateSelector>
                <selector:Selector CellWithBall="{StaticResource CellWithBall}"/>
            </ItemsControl.ItemTemplateSelector>
        </ItemsControl>

这是 DataTemplate 的示例。

  <DataTemplate x:Key="CellWithBall">
        <Canvas>
            <Rectangle Canvas.Left="{Binding Path=Position.x}" Canvas.Top="{Binding Path=Position.y}"
                       Fill="{Binding Path=BallColour}" Width="{Binding Path=Size}" Height="{Binding Path=Size}"
                       Stroke="Black" StrokeThickness="0.1">
                <Rectangle.InputBindings>
                    <MouseBinding Gesture="LeftClick"
                                  Command="{Binding Path=DataContext.ClickedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
                                  CommandParameter="{Binding}" />
                </Rectangle.InputBindings>
            </Rectangle>
        </Canvas>
    </DataTemplate>

当移动球事件触发时,模型发送到视图模型路径。路径是球必须经过的点列表。示例:在运动场单元格 (0;0) 中绘制球(意味着视图模型中的属性 Position 设置为 (0;0))。比我们想将球移动到单元格(1;1)。逻辑得到这样的路径 {(0;0),(0;1),(1;1)}。

我怎样才能实现这种不破坏 MVVM 实现的动画?如何将路径传递给视图?每一个想法都会受到赞赏。

4

1 回答 1

0

如果您使用的是 MVVM,我假设您在某处有一个 ViewModel(VM)。现在,我们称它为“CellAnimatorVM”。无论如何,假设您的 ItemsView 将存在于一个窗口中,您希望将该窗口的 DataContext 设置为您的 CellAnimatorVM 类。

 <Window.DataContext>
        <local:CellAnimatorVM/>
 </Window.DataContext>

现在,您的“细胞”对象(细胞列表)需要存在于您的 CellAnimatorVM 类中。您的 CellAnimatorVM 类将负责更改 Cells 列表中每个 Cell 的 Position。

为了将这些更改传达给您的控件,您需要将 INotifyPropertyChanged 添加到 Cell 类中,并且每当设置 Position 时,您需要在设置值之后从设置器中调用 OnPropertyChanged("Position") :

private Position _position;

public Position Position
{
   get{ return _position;}
   set
   {
      _position = value;
      OnPropertyChanged("Position");
   }
}

这应该让你着迷。

仅供参考: INotifyPropertyChanged 的​​简单实现如下:

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string prop)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

#endregion
于 2013-07-05T15:33:06.120 回答