如何将 TabItems 上的 header 文本居中
How to center header texts on TabItems
我正在尝试让我的 WPF TabItems 将它们的 header 文本居中。但无论我在 ContentPresenter 及其包含的 Border 上设置 HorizontalAlignment 和 HorizontalAlignment 的哪种组合(居中或拉伸),文本始终显示为左对齐,而不是居中。我也没有在 TabItems 上看到 属性,我可以使用它直接在选项卡项目本身上设置它(事实证明,TabItem 上的 HorizontalAlignment 做了完全不同的事情)。
我现在的代码是这样的:
<Grid TextElement.Foreground="White" TextElement.FontSize="17" TextElement.FontFamily="Times New Roman" HorizontalAlignment="Center" >
<Border Name="TabBorder" BorderThickness="8 8 8 0" CornerRadius="12 12 0 0"
Background="{StaticResource bandBrush}" HorizontalAlignment="Center" >
<ContentPresenter HorizontalAlignment="Stretch" ContentSource="Header" Height="24" Width="100" />
</Border>
</Grid>
您可以将 ContentPresenter 放在标签中,并将 HorizontalAlignment 属性 设置为 Strecth,并将 HorizontalContentAlignment 设置为 Center,
查看 this:
<Grid x:Name="gridTabItem">
<Border x:Name="Border" Margin="0,0,0,0" BorderBrush="{x:Null}" CornerRadius="7,7,0,0" BorderThickness="0" >
<Label x:Name="label" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Stretch"
HorizontalAlignment="Center"
ContentSource="Header" Margin="10,2,10,2"
RecognizesAccessKey="True">
</ContentPresenter>
</Label>
</Border>
<Rectangle x:Name="rectangle" HorizontalAlignment="Left" Height="4" Margin="0,41, 0,0" Stroke="{x:Null}" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" StrokeThickness="0" Fill="{x:Null}"/>
<Rectangle x:Name="rectangle1" HorizontalAlignment="Left" Height="1" Margin="0,43,0,0" Stroke="{x:Null}" StrokeThickness="0" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" Fill="#FFEEEEEE"/>
<Rectangle x:Name="glow" HorizontalAlignment="Left" Height="41" Margin="0" Stroke="{x:Null}" StrokeThickness="0" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" Fill="{x:Null}"/>
</Grid>
我知道这个问题有点老,已经有公认的答案,但我认为我的答案可以帮助别人。
我的问题是我需要均匀分布 TabItem headers(每个 TabItem header 具有相同的宽度)并且 header 中的文本需要居中。这就是我实现这一目标的方式:
TabControl.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FMEA.Resources.Styles"
xmlns:Converters="clr-namespace:FMEA.Converters"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">
<Style x:Key="Custom_TabItem" BasedOn="{StaticResource {x:Type TabItem}}" TargetType="{x:Type TabItem}">
<Setter Property="Width">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<Converters:TabSizeConverter />
</MultiBinding.Converter>
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" />
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" Path="ActualWidth" />
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="tabItem">
<Border x:Name="Border">
<ContentPresenter x:Name="content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="LightGray" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type TabItem}">
<Border x:Name="border">
<ContentPresenter>
<ContentPresenter.Content>
<TextBlock Text="{TemplateBinding Content}"
FontSize="22" HorizontalAlignment="Center" />
</ContentPresenter.Content>
</ContentPresenter>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
TabSizeConverter 在哪里:
class TabSizeConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
TabControl tabCtrl = values[0] as TabControl;
double width = tabCtrl.ActualWidth / tabCtrl.Items.Count;
return width <= 1 ? 0 : width - 1;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
用法示例:
<TabItem Header="MyHeader" Style="{StaticResource Custom_TabItem}">
我正在尝试让我的 WPF TabItems 将它们的 header 文本居中。但无论我在 ContentPresenter 及其包含的 Border 上设置 HorizontalAlignment 和 HorizontalAlignment 的哪种组合(居中或拉伸),文本始终显示为左对齐,而不是居中。我也没有在 TabItems 上看到 属性,我可以使用它直接在选项卡项目本身上设置它(事实证明,TabItem 上的 HorizontalAlignment 做了完全不同的事情)。
我现在的代码是这样的:
<Grid TextElement.Foreground="White" TextElement.FontSize="17" TextElement.FontFamily="Times New Roman" HorizontalAlignment="Center" >
<Border Name="TabBorder" BorderThickness="8 8 8 0" CornerRadius="12 12 0 0"
Background="{StaticResource bandBrush}" HorizontalAlignment="Center" >
<ContentPresenter HorizontalAlignment="Stretch" ContentSource="Header" Height="24" Width="100" />
</Border>
</Grid>
您可以将 ContentPresenter 放在标签中,并将 HorizontalAlignment 属性 设置为 Strecth,并将 HorizontalContentAlignment 设置为 Center, 查看 this:
<Grid x:Name="gridTabItem">
<Border x:Name="Border" Margin="0,0,0,0" BorderBrush="{x:Null}" CornerRadius="7,7,0,0" BorderThickness="0" >
<Label x:Name="label" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center">
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Stretch"
HorizontalAlignment="Center"
ContentSource="Header" Margin="10,2,10,2"
RecognizesAccessKey="True">
</ContentPresenter>
</Label>
</Border>
<Rectangle x:Name="rectangle" HorizontalAlignment="Left" Height="4" Margin="0,41, 0,0" Stroke="{x:Null}" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" StrokeThickness="0" Fill="{x:Null}"/>
<Rectangle x:Name="rectangle1" HorizontalAlignment="Left" Height="1" Margin="0,43,0,0" Stroke="{x:Null}" StrokeThickness="0" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" Fill="#FFEEEEEE"/>
<Rectangle x:Name="glow" HorizontalAlignment="Left" Height="41" Margin="0" Stroke="{x:Null}" StrokeThickness="0" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" Fill="{x:Null}"/>
</Grid>
我知道这个问题有点老,已经有公认的答案,但我认为我的答案可以帮助别人。
我的问题是我需要均匀分布 TabItem headers(每个 TabItem header 具有相同的宽度)并且 header 中的文本需要居中。这就是我实现这一目标的方式:
TabControl.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FMEA.Resources.Styles"
xmlns:Converters="clr-namespace:FMEA.Converters"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">
<Style x:Key="Custom_TabItem" BasedOn="{StaticResource {x:Type TabItem}}" TargetType="{x:Type TabItem}">
<Setter Property="Width">
<Setter.Value>
<MultiBinding>
<MultiBinding.Converter>
<Converters:TabSizeConverter />
</MultiBinding.Converter>
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" />
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" Path="ActualWidth" />
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="tabItem">
<Border x:Name="Border">
<ContentPresenter x:Name="content"
VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Foreground" Value="LightGray" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type TabItem}">
<Border x:Name="border">
<ContentPresenter>
<ContentPresenter.Content>
<TextBlock Text="{TemplateBinding Content}"
FontSize="22" HorizontalAlignment="Center" />
</ContentPresenter.Content>
</ContentPresenter>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
TabSizeConverter 在哪里:
class TabSizeConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
TabControl tabCtrl = values[0] as TabControl;
double width = tabCtrl.ActualWidth / tabCtrl.Items.Count;
return width <= 1 ? 0 : width - 1;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
用法示例:
<TabItem Header="MyHeader" Style="{StaticResource Custom_TabItem}">