TabControl disposes of controls on inactive tabs

不想你离开。 提交于 2019-11-30 14:33:08

问题


I'm using the MVVM pattern for my app. The MainWindow comprises a TabControl with the DataContext mapped to the ViewModel:

<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}" />

The WorkspaceSelector looks like:

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;
  }
}

so that TabOne returns the DataTemplate. TabOne and the other two tabs return the DataTemplate TabTable.

If I run the application and click on each of the tabs twice (1, 2, 3, 1, 2, 3) I don't get what I expect, which is


TabOne's view is created
TabTwo's view is created
TabOne's View is created
TabTwo's view is created

that is, if the TemplateSelector returns a different value, the existing tab's controls are thrown away and the new tab's control's are created, and if the TemplateSelector returns the same value, nothing happens.

This is exactly what I don't want! I'd like the TabControl to keep all the controls on the tabs, and I would like to be able to do something about creating different controls in code for the case where I go from TabTwo to TabThree. I can live without the latter. But how do I tell the TabControl not to throw away each tab's controls when it's not selected?


回答1:


This is a function of the TabControl and is the default behavior.

Basically, to save memory, the TabControl unloads the visual tree that is in its content area and replaces it with a newly crufted up one for the new tab. To prove this to yourself, you can listen to the Unload event on each control you template in and notice that it fires every time you switch tabs.

There are likely 2 reasons you would want to override this behavior:

  1. You believe that there would be a significant performance penalty.
  2. You are losing the state of the controls because any visual state that is being lost is not backed by a ViewModel.

As for #1, you shouldn't be concerned. CPU time is generally cheaper than RAM and the default behavior leans on the cheaper side of the resource equation. If you still feel like you REALLY don't want this behavior, you can see an example of overriding it here: https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Wpf.Example/Controls/NonReloadingTabControl.cs

However, I would consider this a "smell" for potentially a future performance issue you should spend the time figuring out now, rather than delaying figuring it out.

For #2, you have two options:

  1. Make sure every property you want preserved (like IsSelected, etc) is backed by a ViewModel that preserves that state.
  2. Create a persistent UserControl for each tab that you bind to, rather than to ViewModels (Workspaces in your case). There is an example of that in the "Writer" sample for WAF: http://waf.codeplex.com/


来源:https://stackoverflow.com/questions/2238072/tabcontrol-disposes-of-controls-on-inactive-tabs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!