设置Label / TextBox Horizo​​ntalContentAlignment不起作用

时间:2011-11-30 14:06:28

标签: c# wpf xaml .net-4.0

我有一个复合控件有两个部分 - 标签和值。我已经定义了一个名为“ValueAlignment”的依赖项属性,它应该设置控件值部分中文本的水平对齐方式。无论我做什么,对齐都是默认为左。这是两个例子:

enter image description here

enter image description here

如您所见,我已经定义了几个自定义依赖项属性,例如LabelWidth和ValueWidth。这些工作正常,但不是对齐。依赖项属性在OmniBox对象上定义为:

    public static readonly DependencyProperty ValueAlignmentProperty = DependencyProperty.Register("ValueAlignment", typeof(HorizontalAlignment), typeof(OmniBox), new FrameworkPropertyMetadata(HorizontalAlignment.Stretch));
    public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register("LabelWidth", typeof(String), typeof(OmniBox), new FrameworkPropertyMetadata((String)"40*"));
    public static readonly DependencyProperty ValueWidthProperty = DependencyProperty.Register("ValueWidth", typeof(String), typeof(OmniBox), new FrameworkPropertyMetadata((String)"60*"));
etc...

    public HorizontalAlignment ValueAlignment
    {
        get { return (HorizontalAlignment)GetValue(ValueAlignmentProperty); }
        set { SetValue(ValueAlignmentProperty, value); }
    }

请注意,Horizo​​ntalContentAlignment的类型HorizontalAlignmentMSDN定义。在我的控件的xaml中,我有一组预定义的模板,它们对应于用于显示绑定数据的不同控件类型,这些模板指的是一组常见的预定义样式。以下是与上面“限制加载”控件相关的所有内容:

<ControlTemplate TargetType="{x:Type local:OmniBox}"  x:Key="OBTextBoxTemplate">
    <Grid x:Name="PART_Grid" Style="{StaticResource GridStyle}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding Path=LabelWidth, RelativeSource={RelativeSource TemplatedParent}}"/>
            <ColumnDefinition Width="{Binding Path=ValueWidth, RelativeSource={RelativeSource TemplatedParent}}"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Label x:Name="PART_Label" Style="{StaticResource LabelStyle}" />
        <TextBox x:Name="PART_Value" Style="{StaticResource TextBoxStyle}"/>
    </Grid>
</ControlTemplate>

<Style x:Key="GridStyle" TargetType="Grid" BasedOn="{StaticResource BaseElement}">
    <Setter Property="Focusable" Value="False" />
</Style>
<Style x:Key="TextBoxStyle" TargetType="TextBox" BasedOn="{StaticResource BaseValueStyle}">
    <Setter Property="Margin" Value="{StaticResource BoxedValueMargin}" />
    <Setter Property="Padding" Value="{StaticResource BoxedValuePadding}" />
    <Setter Property="Text" Value="{Binding Path=Value, RelativeSource={RelativeSource TemplatedParent}}" />
    <Setter Property="IsReadOnly" Value="{Binding Path=ReadOnly, RelativeSource={RelativeSource TemplatedParent}}" />
    <Setter Property="HorizontalContentAlignment" Value="{Binding Path=ValueAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:OmniBox}}}" />
</Style>
<Style x:Key="BaseStyle" TargetType="Control" BasedOn="{StaticResource BaseElement}">
    <Setter Property="Padding" Value="0" />
    <Setter Property="MinWidth" Value="50" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
<Style x:Key="BaseElement" TargetType="FrameworkElement">
    <Setter Property="Margin" Value="0" />
    <Setter Property="MinHeight" Value="15" />
    <Setter Property="HorizontalAlignment" Value="Stretch" />
    <Setter Property="VerticalAlignment" Value="Top" />
</Style>

正如您所看到的,当我尝试将样式化文本框的Horizo​​ntalContentAlignment绑定到OmniBox.ValueAlignment依赖项属性时,橡胶符合道路:

<Setter Property="HorizontalContentAlignment" Value="{Binding Path=ValueAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:OmniBox}}}" />

我也尝试过更简单的版本:

<Setter Property="HorizontalContentAlignment" Value="{Binding Path=ValueAlignment, RelativeSource={RelativeSource TemplatedParent}}" />

但两者都没有效果。请注意,在控制模板,其他的事情由绑定到TemplatedParent自定义属性,比如在控制模板列宽,并在文本框样式的Text属性的风格,但同时这些工作,水平对齐的内容没有。任何人都可以看到我错过了什么导致这不起作用?

1 个答案:

答案 0 :(得分:3)

问题是TextBox的 Horizo​​ntalContentAlignment 属性奇怪地什么都不做。必须设置 TextAlignment 属性。当然,因为我的ValueAlignment依赖属性属于HorizontalAlignment类型,所以我需要一个转换器。 (我无法更改依赖项属性类型,因为其他OmniBox控件模板使用像Label这样支持Horizo​​ntalContentAlignment属性的控件。)

我做了一个简单的转换器:

public class HorizontalTextAlignConverter : BaseConverter, IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if( value is HorizontalAlignment )
        {
            switch( (HorizontalAlignment)value )
            {
                case HorizontalAlignment.Center:
                    return TextAlignment.Center;
                case HorizontalAlignment.Left:
                    return TextAlignment.Left;
                case HorizontalAlignment.Right:
                    return TextAlignment.Right;
                case HorizontalAlignment.Stretch:
                    return TextAlignment.Justify; //Arbitrary
            }
        }
        throw new ArgumentException("This converter is intended to convert HorizontalAlignment to TextAlignment and vice versa.");
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

然后改变了我的风格绑定了一点:

<Style x:Key="TextBoxStyle" TargetType="TextBox" BasedOn="{StaticResource BaseValueStyle}">
    ...
    <Setter Property="TextAlignment" Value="{Binding Path=ValueAlignment, RelativeSource={RelativeSource TemplatedParent}, Converter={converters:HorizontalTextAlignConverter}}" />
</Style>

突然之间,一切都神奇地美味: enter image description here

呼。这花了太长时间才搞清楚。