2010-02-10 34 views
3

我正在爲我的應用程序使用MVVM模式。的主窗口包括與映射到視圖模型的一個DataContextTabControlTabControl處理非活動選項卡上的控件

<Window.Resources> 
    <ResourceDictionary> 
    <DataTemplate x:Key="templateMainTabControl"> 
     <ContentPresenter Content="{Binding Path=DisplayName}" /> 
    </DataTemplate> 

    <local:ViewModel x:Key="VM" /> 
    <local:WorkspaceSelector x:Key="WorkspaceSelector" /> 
    <local:TabOneView x:Key="TabOneView" /> 
    <local:TabTableView x:Key="TabTableView" /> 

    <DataTemplate x:Key="TabOne"> 
     <local:TabOneView /> 
    </DataTemplate> 

    <DataTemplate x:Key="TabTable"> 
     <local:TabTableView /> 
    </DataTemplate> 

    </ResourceDictionary> 
</Window.Resources> 


<TabControl Grid.Row="0" 
      DataContext="{StaticResource VM}" 
      ItemsSource="{Binding Workspaces}" 
      SelectedItem="{Binding SelectedWorkspace}" 
      ItemTemplate="{StaticResource templateMainTabControl}" 
      ContentTemplateSelector="{StaticResource WorkspaceSelector}" /> 

WorkspaceSelector看起來像:

public class WorkspaceSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
    Window win = Application.Current.MainWindow; 
    Workspace w = (Workspace) item; 
    string key = w.DisplayName.Replace(" ", ""); 
    if (key != "TabOne") 
    { 
     key = "TabTable"; 
    } 
    return win.FindResource(key) as DataTemplate; 
    } 
} 

使得TabOne返回DataTemplateTabOne,另外兩個選項卡返回DataTemplateTabTable

如果我運行應用程序,點擊每個選項卡的兩次(1,2,3,1,2,3)我沒有得到我所期望的,這是


塔博恩的視圖中創建
TabTwo的視圖中創建
塔博恩的觀點是建立
TabTwo的視圖中創建

也就是說,如果TemplateSelector返回不同的值,現有標籤的控件都扔掉了,新的選項卡的控件的創建,如果TemplateSelector返回ns值相同,沒有任何反應。

這正是我不想要的!我希望TabControl能夠保留選項卡上的所有控件,並且我希望能夠在代碼中創建不同的控件,以便從TabTwoTabThree。沒有後者,我可以生活。但是如何告訴TabControl不選擇每個選項卡的控件?

回答

4

這是TabControl的功能,是默認行爲。

基本上,爲了節省內存,TabControl卸載了其內容區域中的可視化樹,並將其替換爲新選項卡中新綁定的樹。爲了證明這一點,您可以聽取模板中每個控件的Unload事件,並注意每次切換選項卡時它都會觸發。

有可能你想覆蓋此行爲兩個原因:

  1. 你相信會有一個顯著的性能損失。
  2. 您正在失去控件的狀態,因爲正在丟失的任何視覺狀態都不由ViewModel支持。

至於#1,你不應該擔心。 CPU時間通常比RAM更便宜,默認行爲依賴於資源等式的更便宜的一面。如果你還是覺得你真的不希望這種行爲,你可以在這裏看到覆蓋它的一個例子: https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Wpf.Example/Controls/NonReloadingTabControl.cs

不過,我認爲這是一個「嗅覺」潛在的未來的性能問題,你應該花時間現在要搞清楚,而不是推遲計算出來。

對於#2,你有兩個選擇:

  1. 請通過保留該狀態的視圖模型確保每一個你想保全的財產(如IsSelected等)的支持。
  2. 爲您綁定到的每個選項卡創建持久UserControl,而不是ViewModels(您的案例中的工作區)。在WAF的「Writer」示例中有一個例子:http://waf.codeplex.com/
+0

謝謝安德森 - 這是理由1(它只是感覺很貴)。我會順其自然。 --Amaca – amaca 2010-02-10 18:31:53

+0

我需要解決#1,我們有datagrids是非常昂貴的設置每個選項卡更改。我如何告訴tabcontrol單獨維護標籤的內容並且不卸載它們? – DarkwingDuck 2011-10-04 23:57:02

+0

@DarkwingDuck:Telerik發現了一個黑客。不瞭解內存使用情況。因人而異。 http://www.pluralsight-training.net/community/blogs/eburke/archive/2009/04/30/keeping-the-wpf-tab-control-from-destroying-its-children.aspx我建議看看其中一個出色的WPF性能工具,用於查看您的perf是否在您認爲的位置丟失。這裏有一個鏈接:http://msdn.microsoft.com/en-us/library/aa969767.aspx – 2011-10-05 02:39:57

相關問題