Попытка унаследовать тему / стиль и применение дополнительных триггеров

StackOverflow https://stackoverflow.com/questions/7827554

Вопрос

Я пытаюсь работать и понимаю иерархию XAML для стилей ... Простым, простой текстовой поле ... виден повсюду для того, чтобы установить цвет фона «отключен» на основе флага «ISENAPPAUD». Отлично, получил это.

Теперь я хочу получить еще один класс из Textbox ... MyTextBox. Для этого класса у меня есть свойство (не свойство зависимости, поэтому я использовал DataTrigger). Итак, я хочу сохранить все обычные действия текстового поля, которые работали, но теперь получите новый триггер, чтобы правильно обновить цвет фона для некоторого другого цвета. Итак, вот что у меня есть. Просто чтобы уточнить, все мои статические ресурсы для цветов - сплошные щетки ...

<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>

Я упускаю что -то простое?

Это было полезно?

Решение

Во -первых, ваш 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.

Если вы сделаете свою собственность имуществом зависимости, которое по умолчанию не позволяет сделать что -то вроде:

<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, оно все равно может получить значение по умолчанию вашего свойства зависимости и вызвать его. Но так как это будет установлено для текстового поля, этот триггер никогда не будет использоваться.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top