wpf 使用 HorizontalContentAlignment 属性将文本与 ContentControl 对齐
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14966804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Aligning Text with a ContentControl using the HorizontalContentAlignment property
提问by Frinavale
I am attempting to apply a "text alignment" to a ContentControl. Since the ContentControl does not have a horizontal or vertical text alignment property like the TextBlock, I am attempting to use the ContentControl's HorizontalContentAlignment property.
我正在尝试将“文本对齐”应用于 ContentControl。由于 ContentControl 没有像 TextBlock 那样的水平或垂直文本对齐属性,我尝试使用 ContentControl 的 HorizontalContentAlignment 属性。
My problem is that I can't get it to work with a ContentControl itself.
我的问题是我无法让它与 ContentControl 本身一起工作。
In my example, I have a content control displaying "hello world" and a button displaying "change it".
在我的示例中,我有一个显示“hello world”的内容控件和一个显示“change it”的按钮。
When I click the button, I set the HorizontalContentAlignment on the content control and on the button. The button's content changes, but the content control's content does not.
当我单击按钮时,我在内容控件和按钮上设置了 HorizontalContentAlignment。按钮的内容会更改,但内容控件的内容不会。
Here is my XAML code:
这是我的 XAML 代码:
<Window x:Class="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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ContentControl x:Name="ctrl" Width="525">
Hello World!
</ContentControl>
<Button x:Name="btn" Grid.Row="1" Content="Change It" Click="btn_Click"/>
</Grid>
</Window>
And here is my VB.NET code for the button click event:
这是我的按钮单击事件的 VB.NET 代码:
Class MainWindow
Private Sub btn_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
If (ctrl.HorizontalContentAlignment = HorizontalAlignment.Left) Then
ctrl.HorizontalContentAlignment = HorizontalAlignment.Right
btn.HorizontalContentAlignment = Windows.HorizontalAlignment.Right
Else
ctrl.HorizontalContentAlignment = HorizontalAlignment.Left
btn.HorizontalContentAlignment = Windows.HorizontalAlignment.Left
End If
ctrl.UpdateLayout()
End Sub
End Class
I am unable to replace my content controls with text blocks for various reasons, but I still need to be able to align the content.
由于各种原因,我无法用文本块替换我的内容控件,但我仍然需要能够对齐内容。
EDIT:
编辑:
While Narohi work around suggestion works, I am still confused about why the content control's HorizontalContentAlignment property doesn't align the content.
虽然 Narohi 解决了建议的工作,但我仍然对为什么内容控件的 HorizontalContentAlignment 属性不对齐内容感到困惑。
I tried a Label control (which inherits from ContentControl) and it's HorizontalContentAlignment property properly aligns the content.
我尝试了一个 Label 控件(从 ContentControl 继承),它的 HorizontalContentAlignment 属性正确地对齐了内容。
(Edit again: I am no longer confused about this, it seems that the HorizontalContentAlignment isn't utilized properly in all cases.)
(再次编辑:我不再对此感到困惑,似乎在所有情况下都没有正确使用 HorizontalContentAlignment。)
Here is my updated XAML code:
这是我更新的 XAML 代码:
<Window x:Class="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>
<ControlTemplate x:Key="AlignmentAwareControl" TargetType="ContentControl">
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<ContentControl x:Name="ctrlTxt" Grid.Row="0"
Template="{StaticResource AlignmentAwareControl}"
HorizontalContentAlignment="Center" Padding="0">Hello World Content Control!</ContentControl>
<Label x:Name="ctrl" Grid.Row="1" HorizontalContentAlignment="Center" Padding="0">Hello World Label!</Label>
<ContentControl x:Name="ctrlImg" Grid.Row="2"
Template="{StaticResource AlignmentAwareControl}"
HorizontalContentAlignment="Center">
<Image Source="C:\Users\Frinavale\Pictures\Business_Woman.jpg"/>
</ContentControl>
<Button x:Name="btn" Grid.Row="3" Content="Change It" Click="btn_Click"/>
</Grid>
</Window>
Here is my updated VB.NET code:
这是我更新的 VB.NET 代码:
Class MainWindow
Private Sub btn_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
If (ctrl.HorizontalContentAlignment = HorizontalAlignment.Left) Then
ctrlImg.SetValue(ContentControl.HorizontalContentAlignmentProperty, Windows.HorizontalAlignment.Right)
ctrlTxt.SetValue(ContentControl.HorizontalContentAlignmentProperty, Windows.HorizontalAlignment.Right)
ctrl.SetValue(ContentControl.HorizontalContentAlignmentProperty, Windows.HorizontalAlignment.Right)
btn.HorizontalContentAlignment = Windows.HorizontalAlignment.Right
Else
ctrlImg.SetValue(ContentControl.HorizontalContentAlignmentProperty, Windows.HorizontalAlignment.Left)
ctrlTxt.SetValue(ContentControl.HorizontalContentAlignmentProperty, Windows.HorizontalAlignment.Left)
ctrl.SetValue(ContentControl.HorizontalContentAlignmentProperty, Windows.HorizontalAlignment.Left)
btn.HorizontalContentAlignment = Windows.HorizontalAlignment.Left
End If
ctrl.UpdateLayout()
End Sub
End Class
I'm looking forward to your advice,
我期待着你的建议
-Frinny
-弗林尼
回答by Nathan Hillyer
Opening up the default control template for ContentControl in Blend reveals why your original approach did not work.
在 Blend 中打开 ContentControl 的默认控件模板揭示了为什么您的原始方法不起作用。
<ControlTemplate TargetType="{x:Type ContentControl}">
<ContentPresenter/>
</ControlTemplate>
The default template does nothing with the HorizontalContentAlignment property which it inherited from Control. Juxtapose this with Label's default template.
默认模板不使用它从 Control 继承的 HorizontalContentAlignment 属性。将此与 Label 的默认模板并置。
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
As we can see, the Label actually binds to the HorizontalContentAlignment. WPF controls are lookless, so there is never a guarantee that a property will be respected by the current ControlTemplate. I would speculate that the WPF designers didn't respect the HorizontalContentAlignment property because people usually place content within that is independent of the ContentControl's properties or perhaps they assumed if someone was going to use such a generic control they would provide their own template, such as...
正如我们所见,Label 实际上绑定到 HorizontalContentAlignment。WPF 控件是无外观的,因此永远无法保证当前 ControlTemplate 会遵守某个属性。我推测 WPF 设计者不尊重 HorizontalContentAlignment 属性,因为人们通常将内容放置在与 ContentControl 属性无关的内容中,或者他们假设如果有人要使用这样的通用控件,他们会提供自己的模板,例如...
<ContentControl x:Name="ctrl" Width="525">
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<Grid>
<ContentPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Grid>
</ControlTemplate>
</ContentControl.Template>
Hello World!
</ContentControl>

