【问题标题】:How can be implemented ball moving animation in WPF using MVVM?如何使用 MVVM 在 WPF 中实现球的移动动画?
【发布时间】:2013-07-05 11:16:52
【问题描述】:

我正在尝试使用 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 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 实现的动画?如何将路径传递给视图?每一个想法都会受到赞赏。

【问题讨论】:

  • 你为什么要强迫一些东西,这只是为了帮助你?我不明白为什么这么多人如此努力地“坚持使用 mvvm”并且只是制作非常复杂的东西...... MVVM 是一种帮助,一种指导,如果它适合你就坚持它,并在它更好的地方打破它打破它。对于您的问题,请在您的自定义控件中处理动画,并且您的视图模型只会收到通知或用于检索重要数据。动画通常应该只依赖于视图(但如果需要,再次打破它):)

标签: .net wpf animation mvvm


【解决方案1】:

如果您使用的是 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

【讨论】:

  • 柯蒂斯,你是对的。这是我的真实代码。 VM 是 DataContext 和 OnPropertyChaneged 用于更新 View。但问题在于动画。我从来没有用过动画。只是最简单的任务。所以我不知道要使用什么控件或其他什么。 @dowhilefor 建议进行自定义控制。好主意。很快就会尝试。
  • 那么您是自动移动单元格,还是根据用户单击某些内容的时间移动它们?如果您要自动移动它们,WPF 会内置动画。如果您在用户单击某些东西时移动它,那么您仍然可以使用 WPF 在一段时间内从 A 点动画到 B 点,它会做到这一点。这是一个博客链接,其中包含有关如何制作动画的良好信息。 blogs.msdn.com/b/wpfsdk/archive/2007/01/15/….
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 2012-01-03
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
相关资源
最近更新 更多