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

发布于 2024-07-30 00:46:05 字数 2121 浏览 3 评论 0原文

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

替代文字

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>

我需要更改什么才能使 TabItem 在 TabControl 中显示为 TabItem?

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

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

I've got a TabControl whose ItemsSource is bound to an observable collection of views (UserControls) each which have as its root element a TabItem. However, when it is displayed, the Header text is in content of each TabItem, as if UserControl wrapper is causing conflicts:

alt text

The TabControl is in 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>

What do I have to change so that TabItems are displayed as TabItems inside the TabControl?

Here are the TabItem views called SmartFormAreaView.xaml:

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

And here is where I create and load each view into the 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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

慢慢从新开始 2024-08-06 00:46:10

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

因此,您可以填充常规 TabItems< /code> 与您的可视化树,或者您对 TabItems 进行子类化,或者对 TabControl 进行子类化以覆盖其 IsItemItsOwnContainerOverride 方法,接受您的类型作为容器。

该方法应如下所示:

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

The TabControl will accept your controls as its controls only if they can be cast to TabItem, not UserControl, or SmartFormAreaView, etc.

So you either fill regular TabItems with your visual tree, or you subclass TabItems, or you subclass the TabControl to override its IsItemItsOwnContainerOverride method, to accept your type as the container.

The method should look as follows:

protected override bool IsItemItsOwnContainerOverride(object item)
{
    return item is YourControlTypeHere || item is TabItem;
}
夏末的微笑 2024-08-06 00:46:09

对于任何 ItemsControl,如果添加到其 Items 集合(直接或通过 ItemsSource)的项目不是该控件的项目容器的实例,则每个项目都包装在项目容器的实例中。 项目容器是一个类,例如 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 博士的 博客,了解各种 ItemsControl 的精彩讨论相关话题。

For any ItemsControl, if the items added to its Items collection (either directly or via ItemsSource) are not instance of that control's item container, then each item is wrapped in an instance of the item container. The item container is a class such as TabItem or ListBoxItem. The item container is normally a ContentControl or HeaderedContentControl, and your actual item is assigned to its Content property, so you can use templates etc to control how the content is presented. You can also style the item container itself using the ItemControl's ItemContainerStyle property.

In this particular case, you should bind ItemsSource to a list of SmartFormAreaPresenters. Then use something like this for the tab control:

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

where HeaderText is a suitable property on your SmartFormAreaPresenter. You should also remove the TabItem from your SmartFormAreaView definition. The DataContext of each View will automatically be set to the appropriate Presenter.

See Dr. WPF's blog for an excellent discussion of various ItemsControl related topics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文