2011-09-09 76 views
1

我需要在不同的流程开始时显示某种动画。我最初的想法是简单地将一些<ContentControl>标签添加到XAML中,并将它们绑定到View Model对象中的一个属性,然后将该属性简单地分配给ProgressBar,一些繁忙的微调器或其他任何东西。动态呈现控件的MVVM方式

这个工程,但我不喜欢它。我不喜欢它的主要原因是因为视图模型不应该将自己介入到演示文档中,而且这种模式明显打破了这种模式。

这差不多就是我的(丑陋的)的代码看起来像ATM:

XAML:

<ContentControl Content="{Binding ProcessAAnimation}" /> 

在视图模型类:

public object ProcessAAnimation 
{ 
    get { return _processAAnimation; } 
    private set 
    { 
     _processAAnimation = value; 
     OnPropertyChanged("ProcessAAnimation"); 
    } 
} 

public object IsProcessARunning 
{ 
    get { return _processARunning; } 
    private set 
    { 
     if (value == _processARunning) 
      return; 
     _processRunnings = value; 
     if (value) 
      ProcessAAnimation = SomeNiftyAnimationControl(); 
     else 
     { 
      if (ProcessAAnimation is IDisposable) 
       ((IDisposable)ProcessAAnimation).Dispose(); 
      ProcessAAnimation = null; 
     } 
    } 
} 

// (clipped: More properties for "Process B", "Process C" and so on) 

那么,有没有更好的模式为了达成这个。最好是,我可以单独使用XAML动态创建动画控件的模式?

请注意,我已经测试,我声明了三个不同的动画控件,然后结合自己的Visibility属性视图模型状态的解决方案。然而,这在我的书中低于标准,因为我不想隐藏控件,我希望它们在没有需要的情况下消失。此外,这也将使不可能动态地使用不同类型的动画来满足任何需求。

有人吗?

+0

当MVVM是断裂的点,附加的行为(http://www.codeproject.com/KB/WPF/AttachedBehaviors.aspx)来救援。另外探索PRISM(http://compositewpf.codeplex.com/)可能允许你在一个共同的内容区域适应动态视图。 –

回答

2

嗯,你的视图模型知道关于操作和进步本身。其余的可以通过触发器完成。至少那是我们这样做的方式。所以你的ViewModel有一个属性“IsLoadingImage”,例如,当viewmodel启动一个BackgroundWorker来加载一个大图像时它会被设置,它也返回BackgroundWorker“ImageLoadingProgress”报告的进度,现在这两个属性足以传递给你的View 。您的视图由特殊动画的进度条或自定义控件组成。现在,您可以在触发器中绑定“IsLoadingImage”以切换ProgressBar/Animation控件的可见性,并将这些值绑定到“ImageLoadingProgress”。

就像我说的,这就是我们如何处理它,我们的应用程序使用了大量的MVVM的。

的评论编辑回应:如何更改模板触发

<ControlTemplate x:Name="ActiveTemplate" TargetType="{x:Type MyType}"> 
    <!-- Template when active --> 
</ControlTemplate> 

<ControlTemplate x:Name="DeactivatedTemplate" TargetType="{x:Type MyType}"> 
    <!-- Template when deactivated --> 
</ControlTemplate> 

<Style TargetType="{x:Type MyType}"> 
    <Setter Property="Template" Value="{StaticResource DeactivatedTemplate}"/> 

    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsActive}" Value="True"> 
      <Setter Property="Template" Value="{StaticResource ActiveTemplate}"/> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

这假定MyType是具有ControlTemplate可以控制,而且DataContext有一个属性IsActive来切换模板。

+0

是的,我之前做过(通过VM控制动画的可见性),但我更愿意仅在需要时才实例化进度动画控件,然后将它们处理掉。主要出于性能原因,我更喜欢这种方法。所以,基本上,我想知道的是:我可以通过使用触发器实例化和处理通过XML的控件吗? –

+0

当然,例如,您可以更改Trigger中ContentControl的ContentTemplate。 – dowhilefor

+0

这听起来很有趣。你认为你可以给出一个非常简短的代码示例,只是为了让我在正确的方向吗? –