代码之家  ›  专栏  ›  技术社区  ›  amaca

TabControl处理不活动选项卡上的控件

  •  3
  • amaca  · 技术社区  · 15 年前

    我正在为我的应用程序使用MVVM模式。主窗口包括 TabControl DataContext 映射到视图模型:

    <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 . 禁忌 另外两个选项卡返回 数据板 TabTable .

    如果我运行应用程序并单击每个选项卡两次(1、2、3、1、2、3),我就得不到我所期望的,即


    Tabone的视图已创建
    创建TabTwo的视图
    Tabone的视图已创建
    创建TabTwo的视图

    也就是说,如果 TemplateSelector 返回另一个值,放弃现有选项卡的控件并创建新选项卡的控件,如果 模板选择器 返回相同的值,不会发生任何情况。

    这正是我不想要的!我想要 选项卡控件 为了让所有的控件都保持在选项卡上,我希望能够在代码中为我所处的位置创建不同的控件 TabTwo TabThree . 没有后者我也能活下去。但我该怎么告诉 选项卡控件 不选择每个选项卡时不丢弃其控件?

    1 回复  |  直到 10 年前
        1
  •  4
  •   Anderson Imes    10 年前

    这是 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 对于绑定到的每个选项卡,而不是视图模型(本例中的工作空间)。在WAF的“writer”示例中有一个这样的例子: http://waf.codeplex.com/
    推荐文章