2012-06-21 37 views
0

我正在定義一個策略,其中主視圖將使用數據模板在視圖之間切換。目前,它可以在3個視圖之間切換:使用數據模板時的視圖/視圖模型的生存期

  • ApplicationView:它實際上是一個由大量的 不同意見的看法,大多是從分層使用標籤/對接。這是處理應用程序數據的 視圖。
  • LogInView:它用於登錄用戶。
  • DialogView:它用於顯示對話框視圖。該視圖還將使用數據模板來選擇所需的適當視圖。

想法是當需要顯示對話視圖時,它被設置爲主視圖上的當前視圖。選擇完成後,此信息將傳遞給ApplicationView或屬於ApplicationView的視圖。當顯示DialogView時,ApplicationView不能從內存中釋放,因爲它的ApplicationViewModel仍然會使用數據操作(它需要在後臺持續工作)。

我想實現這個使用的DataTemplates,而ContentControl中的內容結合到CurrentView:

// in MainView 
DataTemplate DataType="{x:Type vm:ApplicationViewModel}"> 
    <vw:ApplicationView /> 
</DataTemplate> 

..... 

// in MainViewModel 
public ViewModelBase CurrentView { get; set; } 

基本上我試圖避免使用模態窗口的對話框。

1)這個策略是否正確,或者有些問題我不知道? 2)當我切換到DialogView(我實際上切換viewmodels)時,ApplicationView/ApplicationViewModel會發生什麼?我是否需要在某處存儲ApplicationViewModel的引用,所以它不會收集垃圾?我沒有測試過,但可能當我設置CurrentView時,將會創建一個ViewModel/View的新實例。

3)連接到第二個問題時,使用DataTemplates時,以前使用過的View/ViewModel會發生什麼變化,現在被替換爲不同的view/viewmodel?

回答

0
  1. 我看不出有什麼毛病你切換視圖的方式,儘管通常你不想甩掉,當你顯示應用程序的不對話。

    我已經在過去做什麼是把兩個CurrentView,並在Grid所以他們被放置在彼此的頂部DialogView,則有ApplicationViewModel包含一個IDialogViewModelIsDialogVisible屬性,當你想顯示對話框只需填充這兩個字段。(見下面的例子)

  2. 你將不得不存儲ApplicationViewModel的地方,如果你想回去,並避免創建將不再可見UI對象的新ApplicationViewModel

  3. WPF部署,所以切換CurrentViewLoginApplication將擺脫LoginView,並創建一個ApplicationView

    的ContentControl中的內容獲得相應設置爲您ViewModel,所以實際上是被放置在應用視圖模型。每當WPF遇到它不知道如何繪製的VisualTree中的對象時,它將使用包含對象的.ToString()TextBlock來繪製它。通過定義DataTemplate,您告訴WPF如何繪製對象而不是使用其默認方法.ToString()。一旦對象離開VisualTree,爲渲染對象而創建的任何可視對象都將被銷燬。

雖然我會繼續使用你目前有切換視圖,我不會用的LoginApplication,並Dialog觀點,即方法。

通常情況下,LoginView只應登錄時顯示一次,但它可能會再次在Dialog如果允許用戶切換登錄一次登錄。正因爲如此顯示的,我通常顯示的啓動代碼LoginView,然後在登錄成功後顯示ApplicationView

protected override void OnStartup(StartupEventArgs e) 
{ 
    base.OnStartup(e); 

    var login = new LoginDialog(); 
    var loginVm = new LoginViewModel(); 

    login.DataContext = loginVm; 
    login.ShowDialog(); 

    if (!login.DialogResult.GetValueOrDefault()) 
    { 
     Environment.Exit(0); 
    } 

    // Providing we have a successful login, startup application 
    var app = new ApplicationView(); 
    var context = new ApplicationViewModel(loginVm.CurrentUser); 
    app.DataContext = context; 
    app.Show(); 
} 

就像我剛纔說的,我不想隱藏Application當我顯示Dialog,所以我會做的Application

這裏Dialog部分是在DataTemplate我會用的例子我ApplicationViewModel,用我自己的custom Popup from my blog的對話框

<Grid x:Name="ApplicationView"> 
    <ContentControl Content="{Binding CurrentView}" /> 
    <local:PopupPanel x:Name="DialogPopup" 
         Content="{Binding DialogContent}" 
         local:PopupPanel.IsPopupVisible="{Binding IsDialogVisible}" 
         local:PopupPanel.PopupParent="{Binding ElementName=ApplicationView}" /> 
</Grid> 
+0

嗨Rachel,應用程序本身應該「永不」關閉,因此應在每次換檔時運行應用程序時進行登錄。這就是爲什麼我想讓LoginView成爲應用程序的一部分。所以,如果我正確地理解了你,那麼無論我保留對ApplicationViewModel的引用以防止它被丟棄,ApplicationView將會在我切換CurrentView時立即處理掉。但是如果我隱藏視圖,視圖將不會被處置? – Goran

+0

@Goran我看到了,在這種情況下,我只需將'Login'作爲對話彈出窗口之一,或者甚至是應用程序的'CurrentViews'之一。如果ApplicationView不可見,或者通過將其Visibility屬性設置爲不可見,或者通過更改CurrentView以使其不存在,則ApplicationView將被卸載。如果你有要保存的數據,你應該將它存儲在'ApplicationViewModel'中,所以下次你顯示'ApplicationView'時,它會重新加載到最後一個用戶的地方。 – Rachel

0

就我個人而言,我會發現在標準網格中使用ZOrdering更容易,並將所有內容放在同一視圖中 - 使用ViewModel來管理可見性。

<Grid> 
    <Grid Visibility="{Binding IsView1Visible, 
     Converter={StaticResource BoolToVisibilityConverter}}"> 
     <!-- view 1 contents --> 
    </Grid> 
    <Grid Visibility="{Binding IsView2Visible, 
     Converter={StaticResource BoolToVisibilityConverter}}"> 
     <!-- view 2 contents --> 
    </Grid> 
    <Grid Visibility="{Binding IsView3Visible, 
     Converter={StaticResource BoolToVisibilityConverter}}"> 
     <!-- view 3 contents --> 
    </Grid> 
    <Grid Visibility="{Binding IsDialogVisible, 
     Converter={StaticResource BoolToVisibilityConverter}}"> 
     <!-- dialog contents contents --> 
    </Grid> 
</Grid> 
+0

這得到了許多不同的意見非常複雜的,而且是更多的工作,因爲你必須手動管理查看可見性。我發現使用'DataTemplates'來定義應該如何繪製每個'ViewModel',在ContentControl'中顯示'CurrentView'屬性,然後將'CurrentView'設置爲'ViewModel'是最新的。我有一個例子[在我的博客](http://rachel53461.wordpress.com/2011/05/28/switching-between-viewsusercontrols-using-mvvm/)如果你有興趣 – Rachel

相關問題