为什么选项卡标题显示在XAML TabControl的选项卡的内容区域中?

时间:2009-08-04 09:53:32

标签: c# wpf xaml mvp tabcontrol

我有一个 TabControl ,其ItemsSource绑定到可观察的视图集合(UserControls),每个视图的根元素都是 TabItem 。但是,当显示时,标题文本位于每个TabItem的内容中,就像 UserControl 包装器导致冲突一样:

alt text

TabControl位于 SmartFormView.xaml:

<UserControl x:Class="TestApp.Views.SmartFormView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel
        Margin="10">
        <TextBlock Text="{Binding Title}"
            FontSize="18"/>
        <TextBlock Text="{Binding Description}"
            FontSize="12"/>

        <TabControl
            Margin="0 10 0 0"
            ItemsSource="{Binding SmartFormAreaViews}"/>
    </StackPanel>
</UserControl>

我需要更改哪些TabItems在TabControl中显示为TabItems?

以下是名为 SmartFormAreaView.xaml的TabItem视图:

<UserControl x:Class="TestApp.Views.SmartFormAreaView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <TabItem Header="This is the header">
        <StackPanel Margin="10">
            <TextBlock Text="this is the content"/>
        </StackPanel>
    </TabItem>
</UserControl>

这是我创建并将每个视图加载到 ObservableCollection 的地方:

var areas = from area in xmlDoc.Descendants("area")
            select area;
foreach (var area in areas)
{
    SmartFormArea smartFormArea = new SmartFormArea();
    smartFormArea.IdCode = area.Attribute("idCode").Value;
    smartFormArea.Title = area.Attribute("title").Value;
    SmartFormAreaPresenter smartFormAreaPresenter = new SmartFormAreaPresenter(smartFormArea);
    SmartFormAreaViews.Add(smartFormAreaPresenter.View as SmartFormAreaView);
}

2 个答案:

答案 0 :(得分:4)

对于任何ItemsControl,如果添加到其Items集合中的项目(直接或通过ItemsSource)不是该控件的项目容器的实例,则每个项目都包含在项目容器的实例中。 item容器是一个类,如TabItem或ListBoxItem。项容器通常是ContentControl或HeaderedContentControl,并且您的实际项目已分配给其Content属性,因此您可以使用模板等来控制内容的呈现方式。您还可以使用ItemControl的ItemContainerStyle属性设置项容器本身的样式。

在这种特殊情况下,您应该将ItemsSource绑定到SmartFormAreaPresenters列表。然后使用类似这样的选项卡控件:

<TabControl ItemsSource="{Binding SmartFormAreaPresenters}">
  <TabControl.ItemContainerStyle>
    <Style TargetType="{x:Type TabItem}">
      <Setter Property="Header" Value="{Binding HeaderText}" />
    </Style>
  </TabControl.ItemContainerStyle>

  <TabControl.ContentTemplate>
    <DataTemplate DataType="{x:Type local:SmartFormAreaPresenter}">
      <local:SmartFormAreaView />
    </DataTemplate>
  </TabControl.ContentTemplate>
</TabControl>

其中HeaderText是SmartFormAreaPresenter上的合适属性。您还应该从SmartFormAreaView定义中删除TabItem。每个View的DataContext将自动设置为适当的Presenter。

请参阅WPF博士的blog,了解各种与ItemsControl相关的主题。

答案 1 :(得分:0)

TabControl仅当控件可以转换为TabItem,而不是UserControl或SmartFormAreaView等时,才会接受控件作为控件。

因此,您可以使用可视树填充常规TabItems,也可以将TabItems作为子类,或者继承TabControl以覆盖其IsItemItsOwnContainerOverride方法,以接受您的类型作为容器。

该方法应如下所示:

protected override bool IsItemItsOwnContainerOverride(object item)
{
    return item is YourControlTypeHere || item is TabItem;
}