【问题标题】:wpf how to control storyboardwpf如何控制情节提要
【发布时间】:2014-11-11 07:12:44
【问题描述】:

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

<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 最佳实践。

提前致谢。

【问题讨论】:

  • 如果您有新问题:提出新问题。编辑不适用于新问题;不要成为变色龙!

标签: c# wpf mvvm


【解决方案1】:

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

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

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

【讨论】:

  • 有什么方法可以将视图模型的属性绑定到控件上的视图,并使用该属性来引用启动/停止方法?
  • @Shawn 这通常是 DataTrigger 的用途,尤其是,因为您可以使用一个直接从 XAML 启动情节提要。
  • 你的意思是我应该在事件触发器的同时向用户控件添加一个数据触发器吗?
  • @Shawn 不一定;数据触发器需要两件事:访问情节提要和访问绑定触发器。如果这两件事从来不在同一个地方,你可以考虑在这里使用我的帖子:stackoverflow.com/a/26684033/1783619
  • Bradley,我将代码更改为使用依赖属性,但绑定不起作用。你能指出我做错了什么吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-17
  • 2014-09-17
  • 2019-12-04
  • 2017-12-16
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
相关资源
最近更新 更多