选项卡标题:如果实际选项卡标题长度超出,内容不会自动拉伸

7
我是一名有用的助手,可以为您翻译文本。
我有一个TabControl并尝试使标签页看起来更好。我有以下XAML代码:
(在“Resources.xaml”中:)
<DataTemplate x:Key="ClosableTabItemTemplate">
    <DockPanel LastChildFill="True" MinWidth="200" Height="20" HorizontalAlignment="Stretch" behaviors:MouseClickBehavior.ClickCommand="{Binding Path=CloseCommand}">
        <Image Source="{Binding Path=Image}" Height="16" VerticalAlignment="Center" />
        <Button Background="Transparent"
                  BorderBrush="Transparent"
                  Command="{Binding Path=CloseCommand}"
                  Content="X"
                  Cursor="Hand"
                  DockPanel.Dock="Right"
                  Focusable="False" 
                  FontSize="9"
                  FontWeight="Bold"
                  Margin="3,0,0,0"
                  Padding="0"
                  VerticalAlignment="Center"
                  VerticalContentAlignment="Center"
                  Width="16" Height="16" />
        <TextBlock Text="{Binding Path=Header}" DockPanel.Dock="Left" VerticalAlignment="Center" />
    </DockPanel>
</DataTemplate>

(在MainWindow.xaml中:)
<TabControl Grid.Column="1"
            ItemsSource="{Binding Path=Tabs}"
            ItemTemplate="{DynamicResource ClosableTabItemTemplate}" />

这是我的问题的可视化示例:
我现在喜欢选项卡的实际宽度,但是头部的dockpanel没有填充所有空间,这让人感到困扰。如果使用Grid(可能是任何容器控件),也会出现相同的情况。
3个回答

8
TabItem 的默认样式中,ContentPresenter.HorizontalAlignment 绑定到 ItemsControl.HorizontalContentAlignment。以下是从 Aero.NormalColor.xaml 中提取的样式代码:
<ContentPresenter Name="Content"
                  ContentSource="Header"
                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                  HorizontalAlignment="{Binding Path=HorizontalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                  VerticalAlignment="{Binding Path=VerticalContentAlignment,RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
                  RecognizesAccessKey="True"/>

TabControl.HorizontalContentAlignment 设置为 Stretch 对我解决了这个问题。

<TabControl HorizontalContentAlignment="Stretch" />

3
太好了!这比其他解决方案容易多了。 - Daniel Sklenitzka
2
太棒了,一行代码就解决了问题,显然我应该早点想到。 - apc
3
非常好的简洁回答! :) - VibeeshanRC

3

我曾遇到过可关闭选项卡的视觉问题,并通过扩展TabControl(稍后在XAML中使用)和TabItem类来解决。我在前者中重写了GetContainerForItemOverride()方法,在后者中重写了OnApplyTemplate()方法。我创建了一个DependencyObject扩展方法来查找TabItemContentPresenter元素,并将其HorizontalAlignment属性设置为HorizontalAlignment.Stretch

public class MyTabControl : TabControl
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new MyTabItem();
    }
}

public class MyTabItem : TabItem
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        var content = this.GetFirstDescendantOfType<ContentPresenter>();
        if (content != null)
        {
            content.HorizontalAlignment = HorizontalAlignment.Stretch;
        }
    }
}

public static class DependencyObjectExtensions
{
    public static T GetFirstDescendantOfType<T>(this DependencyObject parent) where T : DependencyObject
    {
        if (parent == null)
        {
            return null;
        }
        else
        {
            var children = parent.GetChildren();
            T descendant = children.FirstOrDefault(child => child is T) as T;

            if (descendant == null)
            {
                foreach (var child in children)
                {
                    if ((descendant = child.GetFirstDescendantOfType<T>()) != null) break;
                }
            }

            return descendant;
        }
    }

    public static IEnumerable<DependencyObject> GetChildren(this DependencyObject parent)
    {
        var children = new List<DependencyObject>();

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        {
            children.Add(VisualTreeHelper.GetChild(parent, i));
        }

        return children;
    }
}

我的XAML代码如下:
(在MainWindowResources.xaml中):
<DataTemplate x:Key="ClosableTabItemTemplate">
    <DockPanel>
        <Button Command="{Binding Path=CloseCommand}"
                Content="X"
                Cursor="Hand"
                DockPanel.Dock="Right"
                Focusable="False"
                FontFamily="Courier"
                FontSize="9"
                FontWeight="Bold"
                Margin="8,1,0,0"
                Padding="0"
                VerticalContentAlignment="Bottom"
                Width="16"
                Height="16"
                ToolTip="Close" />
        <TextBlock Text="{Binding Path=DisplayName}"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center" />
    </DockPanel>
</DataTemplate>

(在 MainWindow.xaml 中): 注意使用自定义的 MyTabControl 控件

<MyTabControl IsSynchronizedWithCurrentItem="True"
              ItemsSource="{Binding Path=ClosableViewModels}"
              ItemTemplate="{StaticResource ClosableTabItemTemplate}"
              Margin="4" />

我爱你!我已经花了2个小时来尝试让我的自定义TabHeader UserControl填充/拉伸Tab的宽度。您的ControlHelper和OnApplyTemplate()解决了我的问题。 - TyCobb

2
尝试覆盖ItemContainerStyle.Template而不是ContentTemplate
我以前也做过类似的事情,尽管我重写了整个TabControl模板,所以有点难以看出我在做什么。我的代码如下:
<ControlTemplate x:Key="CurvedTabItemTemplate" TargetType="{x:Type TabItem}">
    <DockPanel Width="200">
        <ContentPresenter x:Name="ContentSite" ContentSource="Header" RecognizesAccessKey="True" />
    </DockPanel>
</ControlTemplate>

<Style x:Key="CurvedTabItemStyle" TargetType="{x:Type TabItem}">
    <Setter Property="Template" Value="{StaticResource CurvedTabItemTemplate}" />
</Style>

<TabControl Grid.Column="1" ItemsSource="{Binding Path=Tabs}" 
            ContentTemplate="{DynamicResource ClosableTabItemTemplate}"
            ItemContainerStyle="{DynamicResource CurvedTabItemStyle}" />

这给了我一些奇怪的行为,选项卡的内部内容和选项卡标题被翻转了...不过还会继续尝试不同的方法... - Andrew
明白了。事实证明我完全看错了文件。 - Andrew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接