1

我想让我的错误模板看起来不同,具体取决于装饰控件上的某些属性值。

如下设置 TargetType 会导致运行时异常:“TextBox”ControlTemplate TargetType 与模板化类型“Control”不匹配。因此,ErrorTemplate 似乎必须使用“Control”的 targetType。

<ControlTemplate x:Key="ValidationErrorTemplate" TargetType={x:Type TextBox}>
  <Grid>
    <AdornedElementPlaceholder  HorizontalAlignment="Left" Name="placeholder"/>
    <Grid Background="Yellow">
      <Grid.Style>
        <Style TargetType="Grid">
          <Style.Triggers>
            <DataTrigger Binding="{TemplateBinding IsReadOnly}" Value="True">
              <Setter Property="Background" Value="Green"/>
            </DataTrigger>
          </Style.Triggers>
        </Style>
      </Grid.Style>
    </Grid>
  </Grid>
</ControlTemplate>

我删除了targetType,然后尝试了这个:

<DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}" Value="True">
  <Setter Property="Background" Value="Green"/>
</DataTrigger>

然后这个,没有产生异常,但也没有效果:

<DataTrigger Binding="{Binding AdornedElement.(TextBox.IsReadOnly), ElementName=placeholder}" Value="True">
  <Setter Property="Background" Value="Orange"/>
</DataTrigger>

而这个,没有产生任何例外,但也没有效果:

<DataTrigger Binding="{Binding (TextBox.IsReadOnly), ElementName=placeholder}" Value="True">
  <Setter Property="Background" Value="Orange"/>
</DataTrigger>

最后是这个,它产生了“BindingExpression 路径错误:‘对象’‘AdornedElementPlaceholder’上找不到‘IsReadOnly’属性”:

<DataTrigger Binding="{Binding IsReadOnly, ElementName=placeholder}" Value="True">
  <Setter Property="Background" Value="Green"/>
</DataTrigger>

有没有人对如何在 ErrorTemplate 中引用依赖属性有任何其他想法?

4

1 回答 1

2

正确答案是:

<DataTrigger Binding="{Binding AdornedElement.(TextBox.IsReadOnly), ElementName=placeholder}" Value="True">
  <Setter Property="Background" Value="Orange"/>
</DataTrigger>

虽然这是我早期失败的尝试之一,但我的测试设置存在缺陷。我在网格上设置默认背景属性,而不是在样式中设置它。由于依赖属性的优先级,直接在对象上设置的值将始终胜过在样式中设置的任何值(特别是在我的触发器中)。

这是一个工作设置:

<ControlTemplate x:Key="ValidationErrorTemplate">
  <Grid>
    <Grid.Style>
      <Style TargetType="{x:Type Grid}">
        <Setter Property="Background" Value="Yellow"/>
        <Style.Triggers>
          <DataTrigger Binding="{Binding AdornedElement.(TextBox.IsReadOnly), ElementName=placeholder}" Value="True">
            <Setter Property="Background" Value="Orange"/>
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </Grid.Style>

    <AdornedElementPlaceholder Name="placeholder"/>
  </Grid>
</ControlTemplate>

这里的一个关键是 AdornedElement 始终是 Control 类型,因此您必须进行适当的限定(或强制转换?)才能访问未在 Control 上公开的属性。这是通过类名和属性周围的括号来完成的。另一个例子是:AdornedElement.(CheckBox.IsChecked)。由于 IsChecked 不在 Control 上,因此您必须通过明确说明拥有该属性的类类型来限定它。

于 2014-10-07T12:05:41.807 回答