web-dev-qa-db-fra.com

Pouvez-vous définir plusieurs TargetTypes pour un même style XAML?

En HTML/CSS, vous pouvez définir un style qui peut être appliqué à de nombreux types d'éléments, par exemple:

.highlight {
    color:red;
}

peut être appliqué à la fois à P et DIV, par exemple:

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

mais en XAML, vous semblez devoir définir le TargetType pour les styles, sinon vous obtenez une erreur:

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

existe-t-il un moyen de permettre à un style XAML d'être appliqué à plusieurs éléments ou même de le laisser ouvert comme en CSS?

58
Edward Tanguay

Les setters dans les styles WPF sont vérifiés pendant la compilation; Les styles CSS sont appliqués dynamiquement.

Vous devez spécifier un type afin que WPF puisse résoudre les propriétés des setters en propriétés de dépendance de ce type.

Vous pouvez définir le type cible pour les classes de base qui contiennent les propriétés souhaitées, puis appliquer ce style aux classes dérivées. Par exemple, vous pouvez créer un style pour les objets Control, puis l'appliquer à plusieurs types de contrôles (Button, TextBox, CheckBox, etc.)

<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"/>
68
Josh G
<!-- 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>

Je pense que ces deux méthodes de déclaration d'un style pourraient répondre à votre question. Dans le premier, aucun TargetType n'est spécifié, mais les noms de propriété sont préfixés par 'Label'. Dans le second, le style est créé pour les objets Label.

Une autre méthode pour le faire est:

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

Je voulais appliquer un style à un Textblock et un TextBox mais la réponse sélectionnée ne fonctionnait pas pour moi car Textblock n'hérite pas de Control, dans mon cas, je voulais affecter la propriété Visibility, j'ai donc utilisé FrameworkElement

<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}"/>

Cela fonctionne pour la propriété Visibility car les deux éléments héritent de Frameworkelement et la propriété y est définie. Bien sûr, cela ne fonctionnera pas pour les propriétés définies uniquement dans Control, vous pouvez rechercher dans l'arborescence de la hiérarchie et essayer de trouver une classe de base, de toute façon j'ai pensé que cela pourrait aider quelqu'un car il s'agit d'un résultat de recherche supérieur et la réponse sélectionnée est un peu incomplète.

4
The One

Il existe une autre réponse à la question. Vous POUVEZ laisser le paramètre TargetType hors du style, ce qui lui permettra de s’appliquer à différents contrôles différents, mais uniquement si vous préfixez le nom de la propriété par "Contrôle".

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

Évidemment, cela ne fonctionne que pour les propriétés de la classe de contrôle de base. Si vous essayez de définir ItemsSource, cela échouera car il n'y a pas de Control.ItemsSource

3
PaulMolloy