WPF 将 HorizontalAlignment 绑定到 TextAlignment [英] WPF binding HorizontalAlignment to TextAlignment
问题描述
我有一个 ListBoxItem
,它的 HorizontalAlignment
属性根据 Window
的宽度由转换器更改.我在这个 ListBoxItem
中有一个 TextBlock
,它的 TextAlignment
属性绑定到 ListBoxItem 的
HorizontalAlignment
属性代码>.
I have a ListBoxItem
whose HorizontalAlignment
property is changed by an Converter, according to the width of the Window
. I have a TextBlock
inside this ListBoxItem
whose TextAlignment
property is binded to the HorizontalAlignment
property of the ListBoxItem
.
ListBoxItem
的 HorizontalAlignment
属性正在正确更改;但是,TextBlock
的文本对齐方式保持不变.错误在哪里?
The HorizontalAlignment
property of the ListBoxItem
is changing correctly; however, the text alignment of the TextBlock
remains unchanged. Where is the error?
这是绑定的代码(我没有显示ListBoxItem
的Converter,因为它工作正常(根据Window width
,它从Left
到 Center
)):
Here is the code of the binding (I didn't show the Converter of the ListBoxItem
because it is working correctly (according to the Window width
, it changes from Left
to Center
)):
<ListBox>
<ListBoxItem>
<TextBlock TextWrapping="Wrap" Text="Some text"
TextAlignment="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}, Path=HorizontalAlignment}"/>
</ListBoxItem>
</ListBox>
伙计,你是个侦探!我做了一个有效的实验,但我无法解释为什么.我使用了 MultiBinding 而不是 Binding,传递 AcualWidth 属性,实际上转换器没有使用它.现在 TextAlignment 正在工作并在 ListBoxItem 的 HorizontalAlignment 更改时更新.我使用了以下代码:
Man, you are a detective! I did an experiment that worked, but I can't explain why. I used a MultiBinding instead of a Binding, passing AcualWidth property, which actually is not used by the Converter. Now the TextAlignment is working and is updated when ListBoxItem's HorizontalAlignment changes. I used the following code:
<TextBlock TextWrapping="Wrap" Text="Some text">
<TextBlock.TextAlignment>
<MultiBinding Converter="{StaticResource HorizontalToTextAlignmentConverter}">
<Binding Path="ActualWidth" RelativeSource="{RelativeSource Self}"/>
<Binding Path="HorizontalAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}"/>
</MultiBinding>
</TextBlock.TextAlignment>
</TextBlock>
您能解释一下为什么它适用于 MultiBind 而不是简单的 Binding 吗?无论如何,非常感谢您的帮助!
Could you explain why it worked with MultiBind rather than a simple Binding? Anyway, thanks a lot for your help!
推荐答案
它们是两种不同的枚举:
They are two different enumerations:
TextAlignment 枚举: http://msdn.microsoft.com/en-us/library/system.windows.textalignment(v=vs.110).aspx
HorizontalAlignment 枚举: http://msdn.microsoft.com/en-us/library/system.windows.horizontalalignment(v=vs.110).aspx
虽然 TextAlignment
包含 Center
、Justify
、Left
和 Right
,HorizontalAlignment
包含 Center
、Left
、Right
和 Stretch
.所以,如您所见,它们并不相同.
While TextAlignment
contains Center
, Justify
, Left
and Right
, HorizontalAlignment
contains Center
, Left
, Right
and Stretch
. So, as you see, they are not the same.
如果您想在另一个基础上使用一个转换器,请创建一个转换器.
Create a converter if you want to use one based on the other.
这是一个非常基本的转换器(根据您的喜好进行调整):
Here's a very basic converter (adjust to your liking):
public class HorizontalToTextAlignmentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
TextAlignment textAlignment;
// All I'm doing here is simply getting the integer value of the Enumeration.
switch ((int)value)
{
case 0:
// Left to Left
textAlignment = TextAlignment.Left;
break;
case 1:
// Center to Center
textAlignment = TextAlignment.Center;
break;
case 2:
// Right to Right
textAlignment = TextAlignment.Right;
break;
default:
// Stretch to Justify
textAlignment = TextAlignment.Justify;
break;
}
return textAlignment;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
HorizontalAlignment horizontalAlignment;
// All I'm doing here is simply getting the integer value of the Enumeration.
switch ((int)value)
{
case 0:
// Left to Left
horizontalAlignment = HorizontalAlignment.Left;
break;
case 1:
// Right to Right
horizontalAlignment = HorizontalAlignment.Right;
break;
case 2:
// Center to Center
horizontalAlignment = HorizontalAlignment.Center;
break;
default:
// Justify to Stretch
horizontalAlignment = HorizontalAlignment.Stretch;
break;
}
return horizontalAlignment;
}
}
XAML
测试代码:
<Window.Resources>
<local:HorizontalToTextAlignmentConverter x:Key="h2tAlignmentConverter"/>
</Window.Resources>
<Grid>
<ListBox>
<ListBoxItem HorizontalAlignment="Right">
<TextBlock TextWrapping="Wrap" Text="Some text"
TextAlignment="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=HorizontalAlignment, Converter={StaticResource h2tAlignmentConverter}}"
Width="400"/>
</ListBoxItem>
</ListBox>
</Grid>
MSDN
这些编号的顺序有点偏离,所以我只是进入代码来弄清楚它们.这是他们的代码供您参考:
MSDN
order of these numerations was a bit off, so I just went into the code to figure them out. Here's their code for your reference:
public enum TextAlignment
{
Left = 0,
Right = 1,
Center = 2,
Justify = 3,
}
public enum HorizontalAlignment
{
Left = 0,
Center = 1,
Right = 2,
Stretch = 3,
}
我对您的上一条评论进行了一些思考,我认为由于 TextBlock
本身未在 ListBoxItem
父项中对齐,您可能看不到文本对齐方式的更改.因此,作为一种可能的情况,如果 ListBoxItem
大于 TextBlock
,您将看不到正确的更改.您可以通过将 ListBoxItem
的 HorizontalContentAlignment
绑定到它自己的 HorizontalAlignment
来实现它们对齐的同步.
I thought a bit about your last comment, and I think you may not be seeing changes to the text alignment due to the TextBlock
itself not aligning within the ListBoxItem
parent. So, as one of the possible scenarios, if ListBoxItem
is bigger than TextBlock
, you won't see the proper changes. You can accomplish synchronization of their alignments by binding HorizontalContentAlignment
of ListBoxItem
to its own HorizontalAlignment
.
这是XAML
:
<Grid>
<ListBox>
<ListBoxItem HorizontalAlignment="Left" BorderThickness="1" BorderBrush="Red"
Width="400" HorizontalContentAlignment="{Binding RelativeSource={RelativeSource Self}, Path=HorizontalAlignment}">
<TextBlock TextWrapping="Wrap" Text="Some text" Background="Green" Foreground="White"
TextAlignment="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=HorizontalAlignment, Converter={StaticResource h2tAlignmentConverter}}"
Width="300"/>
</ListBoxItem>
</ListBox>
</Grid>
这是不同对齐方式的直观表示.ListBoxItem
是 Red
,TextBlock
是 Green
而 ListBox
占据了整个 网格
&窗口
.
Here's a visual representation of the different alignments. ListBoxItem
is Red
, TextBlock
is Green
and ListBox
occupies the entire Grid
& Window
.
左
对齐:
右
对齐:
居中
对齐:
Stretch
对齐(文本为Justified
):
最好的部分是 HorizontalContentAlignment
只是一个 HorizontalAlignment
,所以不需要转换.
The best part is that HorizontalContentAlignment
is simply a HorizontalAlignment
, so no conversion is needed.
这篇关于WPF 将 HorizontalAlignment 绑定到 TextAlignment的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!