WPF Tabitem 定位

发布于 2024-10-12 07:34:28 字数 133 浏览 3 评论 0原文

例如,使用 WPF 将三个选项卡项放置在选项卡控件的左上角,一个选项卡项放置在右上角,正确的方法是什么?

我尝试通过更改其边距来将第四个 tabitem 向右移动,但这不会产生良好的结果;首先,它被剪短了,其次,它在选择时无法正确显示。

What is the proper way of positioning for example three tabitems at the very top left corner and one at the very top right corner of a tab control using WPF?

I have tried to move the fourth tabitem to the right by changing its margin but this doesn't produce a good result; first of all it is cut short and second of all it does not display correctly when selected.

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

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

发布评论

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

评论(4

八巷 2024-10-19 07:34:28

问题是 TabPanel, TabControl 在内部使用它来布局选项卡,似乎不支持您想要的。一个快速的解决方法是将 TabPanel 替换为其他内容,例如 DockPanel:(

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <TabControl>
        <TabControl.Template>
            <ControlTemplate TargetType="TabControl">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Border BorderThickness="0,0,1,1" BorderBrush="#D0CEBF" Grid.Row="1">
                        <Border BorderThickness="{TemplateBinding BorderThickness}" 
                                BorderBrush="{TemplateBinding BorderBrush}">
                            <Border Background="{TemplateBinding Background}">
                                <ContentPresenter ContentSource="SelectedContent"/>
                            </Border>
                        </Border>
                    </Border>
                    <DockPanel IsItemsHost="True" LastChildFill="False" Margin="2,2,2,0" />
                </Grid>
            </ControlTemplate>
        </TabControl.Template>

        <TabItem Header="Item 1" />
        <TabItem Header="Item 2" />
        <TabItem Header="Item 3" />
        <TabItem Header="Item 4" DockPanel.Dock="Right" />
    </TabControl>
</Window>

参考:这是 用于设置 TabControl 样式的 MSDN 示例。)

简单的 DockPanel 工作起来并不像 TabPanel 那样流畅——选项卡在它们之间切换时会“跳跃”一点,但是这个可能会帮助你开始。也许子类化 TabPanel 并覆盖相关部分会给你一个更准确的结果;我想这取决于你想为此付出多少努力。

The problem is that the TabPanel, which is used internally by the TabControl to lay out the tabs, does not seem to support what you want. A quick workaround would be to replace the TabPanel by something else, for example, a DockPanel:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <TabControl>
        <TabControl.Template>
            <ControlTemplate TargetType="TabControl">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Border BorderThickness="0,0,1,1" BorderBrush="#D0CEBF" Grid.Row="1">
                        <Border BorderThickness="{TemplateBinding BorderThickness}" 
                                BorderBrush="{TemplateBinding BorderBrush}">
                            <Border Background="{TemplateBinding Background}">
                                <ContentPresenter ContentSource="SelectedContent"/>
                            </Border>
                        </Border>
                    </Border>
                    <DockPanel IsItemsHost="True" LastChildFill="False" Margin="2,2,2,0" />
                </Grid>
            </ControlTemplate>
        </TabControl.Template>

        <TabItem Header="Item 1" />
        <TabItem Header="Item 2" />
        <TabItem Header="Item 3" />
        <TabItem Header="Item 4" DockPanel.Dock="Right" />
    </TabControl>
</Window>

(Reference: This is a modified version of an MSDN example for styling a TabControl.)

The simple DockPanel doesn't work as smooth as the TabPanel -- the tabs "jump" a bit when switching between them, but this might get you started. Maybe subclassing the TabPanel and overriding the relevant parts would give you a more accurate result; I guess it depends on how much effort you want to put into this.

梦初启 2024-10-19 07:34:28

我发现通过插入“不可见”选项卡我可以调整间距(即从顶部向下移动选项卡)

例如:

TabItem  Height="100"  Visibility="Hidden" <br>
TabItem..... <br>
TabItem....  <br>

I found that by inserting an "invisible" tab I could adjust the spacing, (i.e. move the tabs down from the top)

For example:

TabItem  Height="100"  Visibility="Hidden" <br>
TabItem..... <br>
TabItem....  <br>
假装不在乎 2024-10-19 07:34:28

您需要更换 TabPanel 在 TabControl 中自定义一些提供所需行为的内容。默认面板都不会提供您想要的行为盒子。

这很可能需要覆盖 MeasureOverrideArrangeOverride 以在根据其包含的项目数量选择所需的面板。

You would need to swap out the TabPanel within the TabControl to something custom which provided the desired behavior. None of the default panels are going to provide your desired behavior out of the box.

This will most likely need to involve overriding MeasureOverride and ArrangeOverride to provide the custom placement within the panel that is desired based on the number of items it contains.

慵挽 2024-10-19 07:34:28

这将涉及 TabControl 的自定义 ControlTemplate。我尝试使用 DockPanel 作为项目主机而不是默认 TabPanel 的示例。

<Style  TargetType="{x:Type TabControl}">
        <Setter Property="OverridesDefaultStyle"
                Value="True" />
        <Setter Property="SnapsToDevicePixels"
                Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <Grid KeyboardNavigation.TabNavigation="Local">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <DockPanel Name="HeaderPanel"
                                   LastChildFill="False"
                                  Grid.Row="0"
                                  Panel.ZIndex="1"
                                  Margin="0,0,4,-1"
                                  IsItemsHost="True"
                                  KeyboardNavigation.TabIndex="1"
                                  Background="Transparent" />
                        <Border Name="Border"
                                Grid.Row="1"
                                Background="WhiteSmoke"
                                BorderBrush="Black"
                                BorderThickness="1"
                                CornerRadius="2"
                                KeyboardNavigation.TabNavigation="Local"
                                KeyboardNavigation.DirectionalNavigation="Contained"
                                KeyboardNavigation.TabIndex="2">
                            <ContentPresenter Name="PART_SelectedContentHost"
                                              Margin="4"
                                              ContentSource="SelectedContent" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

问题是我不知道如何将 DockPanel.Dock 属性公开给 ControlTemplate EG 之外的 TabItems,

<TabControl Margin="10">
    <TabItem Header="Tab One" DockPanel.Dock="Left"/>
    <TabItem Header="Tab Two" DocKPanel.Dock="Left"/>
    <TabItem Header="Tab Three" DocKPanel.Dock="Left"/>
    <TabItem Header="Tab Four" DocKPanel.Dock="Right"/>
</TabControl>

// Note: This does not work!!

我想您将需要编写自己的面板来托管 TabItems;请注意,这将是相当大量的工作,因为您需要处理 TabPanel 中内置的溢出行为之类的事情。

即使您确实尝试了此操作,我认为如果您想在 ControlTemplate 之外公开此功能,您也必须编写自定义 TabControl

如果您想走这条路,请在帖子中查看我的答案

This will involve a custom ControlTemplate for the TabControl. I tried an example using a DockPanel as the items host rather than the default TabPanel.

<Style  TargetType="{x:Type TabControl}">
        <Setter Property="OverridesDefaultStyle"
                Value="True" />
        <Setter Property="SnapsToDevicePixels"
                Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <Grid KeyboardNavigation.TabNavigation="Local">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <DockPanel Name="HeaderPanel"
                                   LastChildFill="False"
                                  Grid.Row="0"
                                  Panel.ZIndex="1"
                                  Margin="0,0,4,-1"
                                  IsItemsHost="True"
                                  KeyboardNavigation.TabIndex="1"
                                  Background="Transparent" />
                        <Border Name="Border"
                                Grid.Row="1"
                                Background="WhiteSmoke"
                                BorderBrush="Black"
                                BorderThickness="1"
                                CornerRadius="2"
                                KeyboardNavigation.TabNavigation="Local"
                                KeyboardNavigation.DirectionalNavigation="Contained"
                                KeyboardNavigation.TabIndex="2">
                            <ContentPresenter Name="PART_SelectedContentHost"
                                              Margin="4"
                                              ContentSource="SelectedContent" />
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

The problem is that I don't know of a way of exposing the DockPanel.Dock property to the TabItems outside of the ControlTemplate E.G.

<TabControl Margin="10">
    <TabItem Header="Tab One" DockPanel.Dock="Left"/>
    <TabItem Header="Tab Two" DocKPanel.Dock="Left"/>
    <TabItem Header="Tab Three" DocKPanel.Dock="Left"/>
    <TabItem Header="Tab Four" DocKPanel.Dock="Right"/>
</TabControl>

// Note: This does not work!!

I guess you will need to write your own Panel to host the TabItems; Note that this will be quite a lot of work as you will need to handle things like overflow behaviour which is built into the TabPanel.

Even if you did try this I think you would have to write a custom TabControl if you wanted to expose this functionality outside of the ControlTemplate.

If you want to go down this road then see my answer in this post

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