3

我正在尝试使用并理解样式的 XAML 层次结构......在一个简单的文本框中......到处都可以看到如何基于“IsEnabled”标志设置“禁用”背景颜色。太好了,明白了。

现在,我想要另一个派生自 TextBox 的类... MyTextBox。对于这个类,我有一个属性(不是依赖属性,所以我使用的是 DataTrigger)。因此,我想保留所有正常工作的 TextBox 操作,但现在获得新触发器以将背景颜色正确更新为其他颜色。所以,这就是我所拥有的。澄清一下,我所有的颜色静态资源都是实心刷子......

<Style TargetType="TextBox" >
  <Setter Property="FontFamily" Value="Courier New" />
  <Setter Property="FontSize" Value="12" />
  <Setter Property="Foreground" Value="{StaticResource MyForeground}" />
  <Setter Property="Background" Value="{StaticResource MyBackground}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="true">

            <ScrollViewer Name="PART_ContentHost" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource MyDisBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="MyDisBackground"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<!--  Now, my derived (or so I was hoping) style that just adds additional trigger -->
<Style TargetType="local:MyTextBox"  BasedOn="{StaticResource {x:Type TextBox}}" >
  <Style.Triggers>
    <DataTrigger Binding="{Binding Path=IsRequired}" Value="True">
      <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
    </DataTrigger>
  </Style.Triggers>
</Style>

我错过了一些简单的东西吗?

4

1 回答 1

1

首先,您DataTrigger正在查看DataContext您的MyTextBox(而不是控件本身)。因此,查看控件,您需要执行以下操作:

<DataTrigger Binding="{Binding Path=IsRequired, RelativeSource={RelativeSource Self}}" Value="True">
    <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
</DataTrigger>

现在这将设置MyTextBox.Background属性何时MyTextBox.IsRequired为真。但是依赖属性值有一个优先顺序。所以上面将在视觉上改变使用的背景,如:

<local:MyTextBox />

在以下情况下,您的RequiredBackground刷子将不会被使用。相反,您会看到MyDisBackground画笔:

<local:MyTextBox IsEnabled="False" />

在这种情况下,ScrollViewer.Background将更改为MyDisBackground并且不再绑定到该MyTextBox.Background属性。MyTextBox.Background仍然是RequiredBackground,但它不再在任何地方使用。

最后,在以下情况下,您的RequiredBackground刷子将不会被使用。

<local:MyTextBox Background="Yellow" />

在这里,本地值(黄色)在优先级列表中位于 #3,而样式设置器位于 #8。

如果您使您的属性成为默认为 false 的依赖属性,那么您可以执行以下操作:

<Style TargetType="TextBox" >
  <Setter Property="FontFamily" Value="Courier New" />
  <Setter Property="FontSize" Value="12" />
  <Setter Property="Foreground" Value="{StaticResource MyForeground}" />
  <Setter Property="Background" Value="{StaticResource MyBackground}" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            Background="{TemplateBinding Background}" 
            SnapsToDevicePixels="true">

            <ScrollViewer Name="PART_ContentHost" 
                Background="{TemplateBinding Background}" 
                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Border>

        <ControlTemplate.Triggers>
          <Trigger Property="local:MyTextBox.IsRequired" Value="False">
            <Setter Property="Background" Value="{StaticResource RequiredBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="RequiredBackground"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{StaticResource MyDisBackground}" />
            <Setter TargetName="PART_ContentHost" Property="Background" 
                 Value="MyDisBackground"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

<Style TargetType="local:MyTextBox"  BasedOn="{StaticResource {x:Type TextBox}}" />

即使 TextBox 不存在该属性,它仍然可以获取您的依赖属性的默认值并触发它。但由于它是为 TextBox 设置的,因此永远不会使用该触发器。

于 2011-10-19T21:00:57.700 回答