Попытка унаследовать тему / стиль и применение дополнительных триггеров - PullRequest
3 голосов
/ 20 октября 2011

Я пытаюсь работать и понять иерархию 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>

Я что-то упустил?

1 Ответ

1 голос
/ 20 октября 2011

Во-первых, ваш DataTrigger смотрит на DataContext вашего MyTextBox (а не на сам элемент управления).Итак, посмотрите на элемент управления, вам нужно сделать что-то вроде:

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

Теперь это установит свойство MyTextBox.Background, когда MyTextBox.IsRequired равно true.Но значения свойств зависимостей имеют порядок приоритета .Таким образом, приведенное выше визуально изменит используемый фон:

<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, этот триггер никогда не будет использоваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...