TabControl将控件放置在不活动的选项卡上 [英] TabControl disposes of controls on inactive tabs

查看:96
本文介绍了TabControl将控件放置在不活动的选项卡上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的应用程序使用MVVM模式. MainWindow包含一个TabControl,其中DataContext映射到ViewModel:

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

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返回DataTemplate. TabOne和其他两个选项卡返回DataTemplate TabTable.

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

如果我运行该应用程序并两次单击每个选项卡(1、2、3、1、2、3),我将无法获得预期的结果,

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的视图已创建
TabTwo的视图已创建
TabOne的视图已创建
TabTwo的视图已创建


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

也就是说,如果TemplateSelector返回不同的值,则现有选项卡的控件将被丢弃,而新选项卡的控件将被创建,并且如果TemplateSelector返回相同的值,则不会发生任何事情.

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.

这正是我所不想要的!我希望TabControl将所有控件保留在选项卡上,并且我希望能够针对从TabTwoTabThree的情况在代码中创建不同的控件.我可以没有后者.但是,如何告诉TabControl当未选中每个选项卡时不要放弃它们的控件?

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?

推荐答案

这是TabControl的功能,是默认行为.

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

基本上,为了节省内存,TabControl卸载其内容区域中的可视树,并用新创建的新标签替换它.为了向自己证明这一点,您可以侦听模板所包含的每个控件上的Unload事件,并注意到该事件在每次切换选项卡时都会触发.

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. 您认为这将对性能造成重大影响.
  2. 您正在丢失控件的状态,因为丢失的任何可视状态都不受ViewModel的支持.

对于#1 ,您不必担心. CPU时间通常比RAM便宜,并且默认行为取决于资源方程式的便宜方面.如果您仍然觉得自己确实不想要这种行为,可以在此处查看覆盖它的示例: https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Wpf.Example/Controls/NonReloadingTabControl.cs

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.

对于#2 ,您有两个选择:

  1. 确保要保留的每个属性(例如IsSelected等)都由保留该状态的ViewModel支持.
  2. 为您绑定到的每个选项卡而不是ViewModel(在您的情况下为工作区)创建一个持久性UserControl. WAF的编写器"示例中有一个示例: http://waf.codeplex.com/
  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/

这篇关于TabControl将控件放置在不活动的选项卡上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆