2011-09-09 110 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

這聽起來很有趣。你認爲你可以給出一個非常簡短的代碼示例,只是爲了讓我在正確的方向嗎? –