【问题标题】:WPF TabItem Header - force Button to take up entire Header spaceWPF TabItem Header - 强制 Button 占用整个 Header 空间
【发布时间】:2014-04-04 00:06:37
【问题描述】:

单击 WPF TabItem Header 时,我需要执行命令。

由于 Button 有一个命令,我想我会将 Button 放在 TabItem Header 中。

我希望 Button 占据 TabItem Header 的全部内容,但无论我尝试了什么,我都无法让它这样做。

这是我的简单 XAML 窗口:

TestWindow.xaml

<Window x:Class="ActivePDFMonitor.TestWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TestWindow" Height="300" Width="300">
    <Grid>
        <TabControl>
            <TabItem Header="Tab 1">
                <TextBlock Text="Hello, world"/>
            </TabItem>
            <TabItem>
                <TabItem.HeaderTemplate>
                    <DataTemplate>          
                        <Button Content="+" Background="Green"></Button>
                    </DataTemplate>
                </TabItem.HeaderTemplate>
                <TextBlock Text="Tab 2 contents"/>              
            </TabItem>
        </TabControl>
    </Grid>
</Window>

这是我尝试过但没有奏效的方法

  1. 设置按钮属性HorizontalAlignment="Stretch", VerticalAlignment="Stretch", HorizontalContentAlignment="Stretch", VerticalContentAlignment="Stretch" - 没有视觉效果

  2. 将其他面板(WrapPanel、DockPanel)包裹在 Button 周围 - 没有视觉效果

  3. &lt;Viewbox&gt; 中包裹按钮 - 出于某种原因,这使得按钮占据了整个窗口。

我想我不需要按钮,如果有某种方法可以将命令附加到整个 TabItem 标题(这将是一个可能的解决方案)。

但是,我绝对不想使用 TabControl 的 SelectionChanged 来触发添加新选项卡(沿着这条路走下去,发现它很脆弱,因为 SelectionChanged 是不可预测的)。

我一直在努力解决这个问题,看起来应该很简单。任何想法或见解将不胜感激。

【问题讨论】:

    标签: c# wpf xaml


    【解决方案1】:

    WPF 的TabPanel 控件不会那样摆动。您将需要重新模板 TabControl 以使用不同的面板。 DockPanel 产生你要求的效果:

    <Window x:Class="Test.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <SolidColorBrush x:Key="TabItem.Selected.Background" Color="#FFFFFF"/>
            <SolidColorBrush x:Key="TabItem.Selected.Border" Color="#ACACAC"/>
            <Style x:Key="TabControlStyle1" TargetType="{x:Type TabControl}">
                <Setter Property="Padding" Value="2"/>
                <Setter Property="HorizontalContentAlignment" Value="Center"/>
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Background" Value="{StaticResource TabItem.Selected.Background}"/>
                <Setter Property="BorderBrush" Value="{StaticResource TabItem.Selected.Border}"/>
                <Setter Property="BorderThickness" Value="1"/>
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TabControl}">
                            <Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                                <Grid.RowDefinitions>
                                    <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
                                    <RowDefinition x:Name="RowDefinition1" Height="*"/>
                                </Grid.RowDefinitions>
                                <!-- here is the edit -->
                                <DockPanel x:Name="headerPanel" Background="Transparent" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1" />
                                <Border x:Name="contentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
                                    <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                </Border>
                            </Grid>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Window.Resources>
        <Grid>
            <TabControl Style="{DynamicResource TabControlStyle1}">
                <TabItem Header="Tab 1" DockPanel.Dock="Left">
                    <TextBlock Text="Hello, world"/>
                </TabItem>
                <TabItem Header="Tab 2" DockPanel.Dock="Left">
                    <TextBlock Text="Hello, world"/>
                </TabItem>
                <TabItem Header="Foo bar" />
            </TabControl>
        </Grid>
    </Window>
    

    如果你想在标题中有一个按钮,没有TabItem 包装,你可以重新模板TabItem。您仍然需要处理通过键盘或其他方式选择TabItem 的情况。

            <TabItem>
                <TabItem.Template>
                    <ControlTemplate>
                        <Button>hello</Button>
                    </ControlTemplate>
                </TabItem.Template>
            </TabItem>
    

    【讨论】:

    • 感谢您非常有见地的回复。您确实以我提出的方式回答了这个问题(并教会了我一些东西),所以我投了赞成票并接受了......我想我只是没有足够好地表达/说明它。我实际上正在寻找具有零边距/零填充的 TabItem '+' 按钮。我发现 TabItem 标题有一个默认边距,所以我正在进步。再次感谢。
    • 太棒了,谢谢。太棒了,我不知道你可以完全覆盖 TabItem 的模板。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多