我有一个复合控件有两个部分 - 标签和值。我已经定义了一个名为“ValueAlignment”的依赖项属性,它应该设置控件值部分中文本的水平对齐方式。无论我做什么,对齐都是默认为左。这是两个例子:
如您所见,我已经定义了几个自定义依赖项属性,例如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); }
}
请注意,HorizontalContentAlignment的类型HorizontalAlignment
由MSDN定义。在我的控件的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>
正如您所看到的,当我尝试将样式化文本框的HorizontalContentAlignment绑定到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属性的风格,但同时这些工作,水平对齐的内容没有。任何人都可以看到我错过了什么导致这不起作用?
答案 0 :(得分:3)
问题是TextBox的 HorizontalContentAlignment 属性奇怪地什么都不做。必须设置 TextAlignment 属性。当然,因为我的ValueAlignment依赖属性属于HorizontalAlignment
类型,所以我需要一个转换器。 (我无法更改依赖项属性类型,因为其他OmniBox控件模板使用像Label这样支持HorizontalContentAlignment属性的控件。)
我做了一个简单的转换器:
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>
突然之间,一切都神奇地美味:
呼。这花了太长时间才搞清楚。