WPF TabItem标题 - 强制按钮占用整个标题空间

时间:2014-04-02 23:16:44

标签: c# wpf xaml

我需要在单击WPF TabItem标题时执行命令。

由于Button有一个Command,我想我会把Button放在TabItem Header中。

我希望Button能够占用TabItem Header的全部内容,但无论我尝试过什么,我都无法做到这一点。

这是我的简单XAML窗口:

enter image description here

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. 在Button周围包裹其他面板(WrapPanel,DockPanel) - 没有视觉效果

  3. <Viewbox>中换行按钮 - 由于某种原因,这使得按钮占用了整个窗口。

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

    但是,我绝对不想使用TabControl的SelectionChanged来触发添加新的Tab(因为SelectionChanged是不可预测的,所以发现它很脆弱)。

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

1 个答案:

答案 0 :(得分:4)

WPF的TabPanel控件并没有这样摆动。您需要重新模板TabControl才能使用其他面板。 DockPanel产生您要求的效果:

Tabcontrol using a 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的情况。

Button in a tabitem template

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