当通过 tabcontrol WPF 中的 xaml 视图添加项目时,如何为 tabitem 设置标题?

发布于 2024-12-21 16:08:39 字数 1493 浏览 2 评论 0原文

我将 5 个 XAML 视图(即 UserControls)添加到选项卡控件 WPF。每个UserControl 对应的选项卡项已按预期呈现。但我想知道如何为这些选项卡项目设置标题。有什么办法吗? 注意:我不想将选项卡项直接添加到TabControl

我的 UserControl:

public class TimeConsumingView : UserControl
{
    public string Header
    {
        get { return (string)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Header.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register(
            "Header",
            typeof(string),
            typeof(TimeConsumingView),
            new UIPropertyMetadata(
                "",
                new PropertyChangedCallback(OnHeaderChanged)));
}

我的 Shell 视图:

 <TabControl x:Name="TabControl">
     <TabControl.ItemTemplate>
         <DataTemplate>
             <TextBlock Text="{Binding Header}"  x:Name="grid" />
         </DataTemplate>
     </TabControl.ItemTemplate>
     <!--<local:GeneralView Header="General"/>-->
     <local:TimeConsumingView Header="2006 - 2007"/>
     <local:TimeConsumingView Header="2007 - 2008"/>
 </TabControl>

在本例中,标头未绑定到 TextBlock。从 Snoop 来看,DataContext 似乎无法在 TabItem 标头的 ContentPresenter 之后遍历。

I am adding 5 XAML views (i.e. UserControls) to the Tab Control WPF. The corresponding tab items for each UserControl has rendered as expected. But I wonder how to set header for those tab items. Is there any way? Note: I dont want to add tab items directly to a TabControl.

My UserControl:

public class TimeConsumingView : UserControl
{
    public string Header
    {
        get { return (string)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Header.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register(
            "Header",
            typeof(string),
            typeof(TimeConsumingView),
            new UIPropertyMetadata(
                "",
                new PropertyChangedCallback(OnHeaderChanged)));
}

My Shell view:

 <TabControl x:Name="TabControl">
     <TabControl.ItemTemplate>
         <DataTemplate>
             <TextBlock Text="{Binding Header}"  x:Name="grid" />
         </DataTemplate>
     </TabControl.ItemTemplate>
     <!--<local:GeneralView Header="General"/>-->
     <local:TimeConsumingView Header="2006 - 2007"/>
     <local:TimeConsumingView Header="2007 - 2008"/>
 </TabControl>

In this case, the header not bound to the TextBlock. When seen from Snoop, it seems the DataContext cannot traverse after the ContentPresenter of TabItem Header.

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

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

发布评论

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

评论(2

情仇皆在手 2024-12-28 16:08:39

为什么不想将项目包装在 TabItem 中?

WPF 在渲染时无论如何都会这样做,我怀疑这是你的问题,因为默认情况下 Header 为 null,因此 ItemTemplate 有一个 null DataContext (你可以使用 < a href="http://snoopwpf.codeplex.com/" rel="nofollow">Snoop)

<TabControl x:Name="TabControl">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}"  x:Name="grid" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <!--<local:GeneralView Header="General"/>-->
    <TabItem Header="2006 - 2007">
        <local:TimeConsumingView Header="2006 - 2007"/>
    </TabItem>
    <TabItem Header="2007 - 2008">
        <local:TimeConsumingView Header="2007 - 2008"/>
    </TabItem>
</TabControl>

如果您确实坚持不使用 TabItem 包装器(WPF 默认情况下会插入),请使用 TabItem 样式这将设置标题属性

<Style TargetType="{x:Type TabItem}">
    <Setter Property="Header" Value="{Binding Header}" />
</Style>

Why don't you want to wrap your items in a TabItem?

WPF does that anyways when it renders, which I suspect is your problem because the Header is null by default, so the ItemTemplate has a null DataContext (You can verify this with Snoop)

<TabControl x:Name="TabControl">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}"  x:Name="grid" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <!--<local:GeneralView Header="General"/>-->
    <TabItem Header="2006 - 2007">
        <local:TimeConsumingView Header="2006 - 2007"/>
    </TabItem>
    <TabItem Header="2007 - 2008">
        <local:TimeConsumingView Header="2007 - 2008"/>
    </TabItem>
</TabControl>

If you really insist on not using a TabItem wrapper (which WPF will insert by default), use a TabItem Style which will set the Header property

<Style TargetType="{x:Type TabItem}">
    <Setter Property="Header" Value="{Binding Header}" />
</Style>
赢得她心 2024-12-28 16:08:39

我通过在 ViewModel 中包含一个包含 Tabitem 名称的字符串来处理此问题。然后,我只需使用 XAML 绑定绑定到该字符串。

<TabControl
        ItemsSource="{Binding Workspaces}" 
        SelectedItem="{Binding CurrentPage, Mode=TwoWay}" 
        SelectedIndex="{Binding SelectedWorkspace, UpdateSourceTrigger=PropertyChanged}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                  <TextBlock Text="{Binding Header}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </DockPanel>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

在选项卡的 ViewModel 中,我有一个名为 Header 的属性。

public String Header { get; set; }

public MyConstructor()
{
     Header = "Name of Tab";
}

另一种解决方案是重写 ToString()。

public override string ToString()
{
    return "Name of my Tab";
}

I handle this by having a String in my ViewModel that contains the name of the Tabitem. I then simply bind to that String using XAML Bindings.

<TabControl
        ItemsSource="{Binding Workspaces}" 
        SelectedItem="{Binding CurrentPage, Mode=TwoWay}" 
        SelectedIndex="{Binding SelectedWorkspace, UpdateSourceTrigger=PropertyChanged}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <DockPanel>
                  <TextBlock Text="{Binding Header}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
            </DockPanel>
        </DataTemplate>
    </TabControl.ItemTemplate>
</TabControl>

Inside my ViewModel for the Tab I have a property called Header.

public String Header { get; set; }

public MyConstructor()
{
     Header = "Name of Tab";
}

An alternative solution would be to override ToString().

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