【问题标题】:WPF Tab Control Headers on the left side左侧的 WPF 选项卡控件标题
【发布时间】:2015-06-16 06:07:57
【问题描述】:

我想制作我的自定义选项卡控件样式。标题应该在左侧,内容在右侧。就像标准样式一样可以做到:

上图中选中的元素是活动项目内的网格。如您所见,它与标题完美对齐。

这是我的设计。所选元素也是活动项目内的网格,但它只是在标题后面而不是在它们旁边。如何将此网格与标题对齐?

这些是我的标签项和标签控件的样式:

 <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.ColumnDefinitions>
                        <ColumnDefinition Width="200"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>
                    <TabPanel
                        Name="HeaderPanel"
                        Grid.Row="0"
                        Panel.ZIndex="1" 
                        Margin="0" 
                        IsItemsHost="True"
                        KeyboardNavigation.TabIndex="1"
                        Background="AliceBlue" />
                    <Border 
                            Name="Border" 
                            Grid.Row="1"
                            BorderThickness="0"
                            KeyboardNavigation.TabNavigation="Local"
                            KeyboardNavigation.DirectionalNavigation="Contained"
                            KeyboardNavigation.TabIndex="2" >
                        <ContentPresenter 
                              Name="PART_SelectedContentHost"
                              Margin="4"
                              ContentSource="SelectedContent" />
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type TabItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid>
                    <Border
                        Name="Border"
                        Margin="0"
                        Padding="10,4,4,4"
                        Background="Transparent"
                        Height="30"                               
                        Width="Auto"
                        BorderThickness="0">
                        <ContentPresenter x:Name="ContentSite"
                            VerticalAlignment="Center"                                   
                            HorizontalAlignment="Left"
                            ContentSource="Header"                                   
                            RecognizesAccessKey="True"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Panel.ZIndex" Value="100" />
                        <Setter TargetName="Border" Property="Background" Value="#FFFFFFFF" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="#FF4576a9"></Setter>
                        <Setter TargetName="Border" Property="BorderThickness" Value="6, 0, 0, 0"></Setter>
                        <Setter TargetName="Border" Property="Padding" Value="4"></Setter>
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Border" Property="Background" Value="Yellow" />
                        <Setter Property="Foreground" Value="Orange" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

谢谢。

【问题讨论】:

    标签: c# wpf visual-studio wpf-controls


    【解决方案1】:

    在您的自定义模板中,您需要设置 Grid.Column 而不是 Grid.Row,因为您的网格现在是 2 列/1 行而不是 1 列/2 行

    <ControlTemplate TargetType="{x:Type TabControl}">
        <Grid ...>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <TabPanel
                Name="HeaderPanel" Grid.Column="0" ... />
            <Border Name="Border" Grid.Column="1" ... >
                <ContentPresenter ... />
            </Border>
        </Grid>
    </ControlTemplate>
    

    【讨论】:

    • 谢谢!这是完美的答案。
    【解决方案2】:

    您无需创建自定义控件。您可以使用 tabcontrol 的 TabStripPlacement 属性来实现此功能。

    <TabControl TabStripPlacement="Left">
                <TabItem Header="Tab1">
    
                </TabItem>
                <TabItem Header="Tab2">
    
                </TabItem>
            </TabControl>
    

    您可以参考http://www.wpf-tutorial.com/tabcontrol/tab-positions/https://msdn.microsoft.com/en-us/library/system.windows.controls.tabcontrol.tabstripplacement(v=vs.110).aspx

    【讨论】:

    • TabStripPlacement 对我的自定义样式没有影响。
    • TabStripPlacement = Left 将给出您正在寻找的所需结果。您想将内容放在标题右侧
    • 如果您不制作自定义模板,这将有效。如果您制作自己的模板,则必须像@Rachel 在她的回答中描述的那样做。