【问题标题】:Drop-down TabControl下拉选项卡控件
【发布时间】:2010-09-22 20:32:16
【问题描述】:

我一直在尝试为 WPF 中的 TabControl 创建自定义外观/模板。

我希望选项卡显示在 ComboBox 中。当您从 ComboBox 中选择项目时,我希望选项卡控件的内容区域显示 TabItem 内容。

这是一张显示我正在寻找的图片:

我可以使用带有数据对象和模板的某种主从设置来完成此操作,但问题是我想使用 TabControl XAML 格式设置控件,如下所示:

<TabControl Style="{DynamicResource ComboTabControlStyle}">
   <TabItem Header="TabItem1">
      <TextBlock Text="TabItem1 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
   </TabItem>
   <TabItem Header="TabItem2">
      <TextBlock Text="TabItem2 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
   </TabItem>
   <TabItem Header="TabItem3">
      <TextBlock Text="TabItem3 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
   </TabItem>
</TabControl>

有什么想法或建议吗?

使用不同的 Panel 更改选项卡项的布局非常容易,但 ComboBox 是 ItemsControl,而不是 Panel。

我尝试将 ComboBox 放入 TabControl 模板并将 ComboBox 的 ItemsSource 绑定到 TabControl.Items 属性,但它似乎无法正常工作。

我还尝试创建一个自定义面板,该面板一次只显示一个“选定”项目,并在您单击它时在下拉列表中显示所有项目(基本上是一个“组合框”面板)。我遇到了麻烦,因为视觉效果只能在视觉树中的一个地方。因此,将面板的子项放入弹出窗口会引发异常。

有人有其他想法吗?

感谢您的帮助!

【问题讨论】:

    标签: wpf templates combobox tabcontrol


    【解决方案1】:

    做你想做的事是非常困难的。这非常接近:

    <DockPanel>
        <ComboBox x:Name="ItemSelector" DockPanel.Dock="Top">
            <ComboBox.ItemTemplate>
                <DataTemplate DataType="{x:Type TabItem}">
                    <TextBlock Text="{Binding Header}"/>
                </DataTemplate>
            </ComboBox.ItemTemplate>
            <TabItem Header="TabItem1">
                <TextBlock Text="TabItem1 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </TabItem>
            <TabItem Header="TabItem2">
                <TextBlock Text="TabItem2 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </TabItem>
            <TabItem Header="TabItem3">
                <TextBlock Text="TabItem3 Content!" FontSize="18.667" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </TabItem>      
        </ComboBox>
        <ContentPresenter Content="{Binding SelectedItem.Content, ElementName=ItemSelector}" DockPanel.Dock="Top"/>
        <TextBlock/>
    </DockPanel>
    

    奇怪的是,它在 ComboBox 中显示所选项目:在呈现项目时忽略 ItemTemplate,因此选择框包含一个 TabItem。要修复 this,您必须继承 ComboBox 并实现一个读/写 SelectionBoxItemTemplate 依赖属性,因为出于某种原因,我确信它并不像我现在认为的那样愚蠢,即属性是只读的。

    【讨论】:

    • 感谢您对此进行调查。我很清楚要做到这一点是多么“困难”。在过去的一两天里,我一直在用头撞墙。最后实现了一个自定义控件来解决问题。
    • 它似乎与 ComboBox 编辑功能有关。如果将 IsEditable 设置为 true,则所选项目将正确显示。但在这种情况下,您可以输入所选字段。几乎看起来好像一个“不可编辑”的选择只需要 ComboBox。
    • 不确定是否会有影响,但如果我调整 ComboBox 的样式,我可以让它工作。在 ComboBox 的新模板中,我将 ContentPresenter.Content 属性设置为指向 SelectedItem 而不是 SelectionBoxItem,并将 ContentTemplate 设置为 ItemTemplate 而不是 SelectionBoxItemTemplate。它奏效了。
    • 我想到另一种解决方法是构建一个从 Panel 派生并包含 ComboBox 的自定义控件,以便您可以将其用作 TabControl 模板中的 ItemsPresenter。但还是:真的吗?有那么难吗?
    【解决方案2】:

    新建一个类,继承自panel,里面放一个combo box,做很多父绑定,使用。它会成功的。

    您必须使用自定义类来编写选项卡,因为它们是常规选项卡项。

    【讨论】:

    • 无话可说请不要回答。
    • 我的想法有什么问题?它会起作用,并会为您提供快速解决问题的方法。请问有什么问题吗?
    • 你的想法很好,只是没有帮助。我正在寻找更多关于如何做到这一点的细节。我已经知道可以创建一个自定义类来执行此操作。
    • 对不起,可能不应该投反对票。如果可以的话,我会删除它。必须编辑您的答案才能删除投票。感谢您提供帮助。
    【解决方案3】:

    我找到了解决办法。

    我创建了一个自定义控件类 (MasterDetailControl)。

    这个类有两个模板部分:

    [TemplatePart(Name = "PART_MasterSelector", Type = typeof(Selector))]
    [TemplatePart(Name = "PART_DetailPresenter", Type = typeof(ContentPresenter))]
    

    该控件有一个项目依赖属性:

    public IList Items { ... }
    

    我添加了一个辅助类:

    [ContentProperty("Detail")]
    public class MasterDetail
    {
       public object Master { get; set; }
       public object Detail { get; set; }
    }
    

    放置在 Items DP 中的项目由 MasterDetailControl 处理。如果它们是 MasterDetail 类型,则将主添加到选择器项列表中。对于其他子项类型,将创建一个新的 MasterDetail 对象,并将该对象分配给 master 和 detail 字段。一个单独的列表维护所有生成的 MasterDetail 对象,其索引对应于 Selector 控件中的索引。

    当 Selector 对象上的 SelectionChanged 事件触发时,我将 ContentPresenter 的 Content 属性设置为与所选主对象对应的项目的 Detail 字段。

    如果有人想了解更多细节,请随时发表评论。

    最后,我现在可以将此控件与指定任何选择器对象(ListBox、ComboBox 等)和 ContentPresenter 的简单控件模板一起使用。

    【讨论】:

      猜你喜欢
      • 2021-10-10
      • 1970-01-01
      • 2011-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      相关资源
      最近更新 更多