Можете ли вы определить несколько TargetTypes для одного стиля XAML?

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

  •  03-07-2019
  •  | 
  •  

Вопрос

В HTML / CSS вы можете определить стиль, который может быть применен ко многим типам элементов, например:

.highlight {
    color:red;
}

может быть применен как к P, так и к DIV, например:

<p class="highlight">this will be highlighted</p>
<div class="highlight">this will also be highlighted</div>

но в XAML вам, похоже, нужно определить TargetType для стилей, иначе вы получите сообщение об ошибке:

<Style x:Key="formRowLabel" TargetType="TextBlock">

есть ли способ разрешить применять стиль XAML к нескольким элементам или даже оставить его открытым, как в CSS?

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

Решение

Параметры настройки в стилях WPF проверяются во время компиляции;Стили CSS применяются динамически.

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

Вы можете задать целевой тип базовым классам, которые содержат нужные вам свойства, а затем применить этот стиль к производным классам.Например, вы могли бы создать стиль для объектов управления, а затем применить его к нескольким типам элементов управления (кнопка, текстовое поле, флажок и т.д.).

<Style x:Key="Highlight" TargetType="{x:Type Control}">
    <Setter Property="Foreground" Value="Red"/>
</Style>

...

<Button Style="{StaticResource Highlight}" Content="Test"/>
<TextBox Style="{StaticResource Highlight}" Text="Test"/>
<CheckBox Style="{StaticResource Highlight}" Content="Test"/>

Другие советы

<!-- Header text style -->
<Style x:Key="headerTextStyle">
    <Setter Property="Label.VerticalAlignment" Value="Center"></Setter>
    <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter>
    <Setter Property="Label.FontWeight" Value="Bold"></Setter>
    <Setter Property="Label.FontSize" Value="18"></Setter>
    <Setter Property="Label.Foreground" Value="#0066cc"></Setter>
</Style>

<!-- Label style -->
<Style x:Key="labelStyle" TargetType="{x:Type Label}">
    <Setter Property="VerticalAlignment" Value="Top" />
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="Margin" Value="0,0,0,5" />
</Style>

Я думаю, что оба этих метода объявления стиля могли бы ответить на ваш вопрос.В первом случае не указан TargetType, но имена свойств имеют префикс 'Label'.Во втором случае стиль создается для объектов Label.

Другой способ сделать это -:

<UserControl.Resources>
  <Style x:Key="commonStyle" TargetType="Control">
     <Setter Property="FontSize" Value="24"/>
  </Style>
  <Style BasedOn="{StaticResource commonStyle}" TargetType="ListBox"/>
  <Style BasedOn="{StaticResource commonStyle}" TargetType="ComboBox"/>
</UserControl.Resources>

Я хотел применить стиль к текстовому блоку и текстовому полю, но выбранный ответ у меня не сработал, потому что Textblock не наследуется от элемента управления, в моем случае я хотел повлиять на свойство Visibility, поэтому я использовал Элемент каркаса

<Style x:Key="ShowIfRequiredStyle" TargetType="{x:Type FrameworkElement}">
        <Setter Property="Visibility" Value="Collapsed"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding ShowIfRequiredStyle, UpdateSourceTrigger=PropertyChanged}" Value="true">
                <Setter Property="Visibility" Value="Visible"/>
            </DataTrigger>
        </Style.Triggers>
</Style>

<TextBlock Style="{StaticResource ResourceKey=ShowIfRequiredStyle}"/>
<TextBox Style="{StaticResource ResourceKey=ShowIfRequiredStyle}"/>

Это работает для свойства Visibility, потому что оба элемента наследуются от Frameworkelement и свойство определено там.Конечно, это не сработает для свойств, определенных только в Control, вы можете выполнить поиск в дереве иерархии и попытаться найти базовый класс, в любом случае, я подумал, что это может кому-то помочь, поскольку это лучший результат поиска, а выбранный ответ немного неполный.

Есть альтернативный ответ на этот вопрос.Вы МОЖЕТЕ вообще не указывать параметр TargetType в стиле, что позволит применять его к различным элементам управления, но только в том случае, если вы добавляете к имени свойства префикс "Control".

<Style x:Key="Highlight">
    <Setter Property="Control.Foreground" Value="Red"/> 
</Style> 

Очевидно, что это работает только для свойств базового класса управления.Если вы попытаетесь установить ItemsSource say, это завершится неудачей, потому что нет элемента управления.ItemsSource

У меня это работает

<Style x:Key="HeaderStyleThin"  TargetType="{x:Type Border}">
    <Setter Property="Background" Value="Black" />

    <Style.Resources>
        <Style TargetType="{x:Type TextBlock}">
               <Setter Property="Background=" Value="Red" />
        </Style>
        </Style.Resources>

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