wpf如何控制故事板

本文关键字:故事 控制 何控制 wpf | 更新日期: 2023-09-27 18:28:45

我有一个这样的用户控件。(从代码项目中获得并修改)

<UserControl x:Class="DataTransfer.View.CustomControls.CircularProgressBar"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="120" d:DesignWidth="120"
             Background="Transparent">
  <Grid>
    <Viewbox>
      <Grid x:Name="LayoutRoot" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.RenderTransform>
          <ScaleTransform x:Name="SpinnerScale" ScaleX="1.0" ScaleY="1.0" />
        </Grid.RenderTransform>
        <Canvas RenderTransformOrigin="0.5,0.5" 
                HorizontalAlignment="Center" 
                VerticalAlignment="Center" 
                Width="120" Height="120" >
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="20.1696" 
                            Canvas.Top="9.76358" 
                            Stretch="Fill" Fill="Orange" 
                            Opacity="1.0"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="2.86816" 
                            Canvas.Top="29.9581" Stretch="Fill" 
                            Fill="Black" Opacity="0.9"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="5.03758e-006" 
                            Canvas.Top="57.9341" Stretch="Fill" 
                            Fill="Black" Opacity="0.8"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="12.1203" 
                            Canvas.Top="83.3163" Stretch="Fill" 
                            Fill="Black" Opacity="0.7"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="36.5459" 
                            Canvas.Top="98.138" Stretch="Fill" 
                            Fill="Black" Opacity="0.6"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="64.6723" 
                            Canvas.Top="96.8411" Stretch="Fill" 
                            Fill="Black" Opacity="0.5"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="87.6176" 
                            Canvas.Top="81.2783" Stretch="Fill" 
                            Fill="Black" Opacity="0.4"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="98.165" 
                            Canvas.Top="54.414" Stretch="Fill" 
                            Fill="Black" Opacity="0.3"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="92.9838" 
                            Canvas.Top="26.9938" Stretch="Fill" 
                            Fill="Black" Opacity="0.2"/>
            <Ellipse Width="21.835" Height="21.862" 
                            Canvas.Left="47.2783" 
                            Canvas.Top="0.5" Stretch="Fill" 
                            Fill="Black" Opacity="0.1"/>
          <Canvas.RenderTransform>
          <RotateTransform x:Name ="SpinnerRotate" Angle = "0" />
          </Canvas.RenderTransform>                    
            <Canvas.Triggers>
              <EventTrigger RoutedEvent ="ContentControl.Loaded" >
                <BeginStoryboard>
                  <Storyboard x:Name="CirccularProgressBarStoryBoard">
                    <DoubleAnimation 
                     Storyboard.TargetName ="SpinnerRotate" 
                     Storyboard.TargetProperty ="(RotateTransform.Angle)" 
                     From="0" To="360" 
                     Duration="0:0:01" 
                     RepeatBehavior="Forever"/>
                   </Storyboard>
                </BeginStoryboard>
             </EventTrigger>
           </Canvas.Triggers>
        </Canvas>
      </Grid>
    </Viewbox>
  </Grid>
</UserControl>

背后的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
namespace DataTransfer.View.CustomControls
{
  /// <summary>
  /// Interaction logic for CircularProgressBar.xaml
  /// </summary>
  public partial class CircularProgressBar : UserControl
  {
    public CircularProgressBar()
    {
      InitializeComponent();
      if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        Stop();
    }
    public void Start()
    {
      LayoutRoot.Visibility = Visibility.Visible;
      CirccularProgressBarStoryBoard.Begin();
    }
    public void Stop()
    {
      LayoutRoot.Visibility = Visibility.Collapsed;
      CirccularProgressBarStoryBoard.Stop();
    }
  }
}

在我看来

    <local:CircularProgressBar x:Name="cpb"  Width="30" Height="30" VerticalAlignment="Bottom" Margin="563,0,117.667,278" RenderTransformOrigin="1.096,0.548" IsEnabled="{Binding CpbIsEnabled}" Visibility="{Binding CpbVisibility}"/>

我需要控制停止和重新启动动画。我可以在视图代码后面这样做

private void BeginA(bool pBegin)
{
  if (pBegin == true)
  {
    cpb.CirccularProgressBarStoryBoard.Begin();
    cpb.LayoutRoot.Visibility = Visibility.Visible;
  }
  else
  {
    cpb.CirccularProgressBarStoryBoard.Stop();
    cpb.LayoutRoot.Visibility = Visibility.Hidden;
  }
}

但我希望在视图模型中控制它。我该怎么做?我正在考虑通过在视图模型中设置bool属性来控制启动/停止,但不确定如何将此属性与启动/停止方法联系起来。

只是尝试遵循MVVM的最佳实践。

提前谢谢。

wpf如何控制故事板

ViewModel不应该控制故事板。ViewModel对视图的详细信息一无所知。

现在ViewModel可以设置一个类似LoadingData的属性,然后您可以触发它(使用DataTrigger)来启动情节提要。它还可能引发视图将注册的事件StartingLoad

无论哪种方式,视图都会选择如何处理视图模型引发的状态更改或事件。视图模型不会直接启动或停止情节提要。