2011-05-24 145 views
24

我對WPF和MVVM比較陌生,而且我發現的最困難的事情是如何簡單地在應用程序中切換用戶控件或視圖。在winforms中,要有一個控件移除自己,你會簡單地說this.Parent.Controls.Remove(this);在MVVM-light和WPF中切換views/usercontrols的最佳方式是什麼?

在WPF中沒有通用的父控件,您必須將其轉換爲特定類型(即網格)並將其刪除。

這似乎也打破了MVVM架構。我也嘗試過數據模板和內容展示器,它們工作良好,除了我無法從代碼更改數據上下文外,因爲datacontext始終是viewmodellocator。

頁面是現在在WPF中執行此操作的可接受方式嗎?如果我有一個具有自定義usecontrol的網格,並且我想根據viewModel中的某個變量切換它? WPF中似乎最簡單的任務不能輕鬆完成。

回答

33

你會這樣做在你的父視圖模型。

例如,如果你的頁面(稱之爲PageViewModel)有兩個視圖(ViewModelAViewModelB),你會對PageViewModel稱爲CurrentView的屬性,而這將決定哪些視圖是可見的。當PageViewModel.CurrentView設置爲ViewModelA的實例時,則使用ViewA的DataTemplate來繪製內容。當它被設置爲ViewModelB的實例時,將顯示ViewB的DataTemplate。

<DataTemplate DataType="{x:Type local:PageViewModel}"> 
    <ContentControl Content="{Binding CurrentView}" /> 
</DataTemplate> 

<DataTemplate DataType="{x:Type local:ViewModelA}"> 
    <TextBlock Text="I'm ViewModelA" /> 
</DataTemplate> 

<DataTemplate DataType="{x:Type local:ViewModelB}"> 
    <TextBlock Text="I'm ViewModelB" /> 
</DataTemplate> 

這將是理想的調用,但是如果您想從ViewModelA/B內切換視圖視圖從父視圖命令開關(DataTemplate中爲PageViewModel在這種情況下),則可以任一掛鉤在創建對象時手動創建事件(CurrentView.ChangeViewCommand = this.ChangeViewCommand)或查看消息傳遞系統。 MVVM光有一個簡單的Messenger類,我發現是相當容易使用,或棱鏡擁有更加先進的EventAggregator

如果你想切換視圖爲同一視圖模型,我會建議被用來確定一個模式屬性,該屬性查看使用。例如:

<DataTemplate x:Key="ViewA" DataType="{x:Type local:MyViewModel}"> 
    <TextBlock Text="I'm ViewModelA" /> 
</DataTemplate> 

<DataTemplate x:Key="ViewB" DataType="{x:Type local:MyViewModel}"> 
    <TextBlock Text="I'm ViewModelB" /> 
</DataTemplate> 

<DataTemplate DataType="{x:Type local:MyViewModel}"> 
    <ContentControl Content="{Binding }"> 
     <ContentControl.Style> 
      <Style TargetType="{x:Type ContentControl}"> 
       <Setter Property="ContentTemplate" Value="{StaticResource ViewA}" /> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding Mode}" Value="2"> 
         <Setter Property="ContentTemplate" Value="{StaticResource ViewB}" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </ContentControl.Style> 
    </ContentControl> 
</DataTemplate> 

編輯

我居然看到這樣的問題來了很多,所以貼出一些事情here如果有人有興趣

+0

這差不多就是我一直在尋找對於。如果我理解正確,可以使用DataTriggers綁定到一個值,然後即時切換內容。這是否適用於其他控件,如ContentPresenter? – JReed 2011-05-25 14:02:25

+0

@JReed當然,我不明白爲什麼不。在第二個例子中,我切換了ContentControl的'ContentTemplate'屬性,但是您可以根據觸發器切換任何控件上的幾乎任何屬性 – Rachel 2011-05-25 14:27:34

+0

如果viewModel在初始化之前需要某些數據,那麼它們沒有一個無參數的構造函數? – 2016-01-06 20:49:15

相關問題