web-dev-qa-db-ja.com

1つのXAMLスタイルに対して複数のTargetTypeを定義できますか?

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のように開いたままにしたりする方法はありますか?

58
Edward Tanguay

WPFスタイルのセッターは、コンパイル時にチェックされます。 CSSスタイルは動的に適用されます。

WPFがセッター内のプロパティをそのタイプの依存関係プロパティに解決できるように、タイプを指定する必要があります。

ターゲットタイプを、必要なプロパティを含むベースクラスに設定し、そのスタイルを派生クラスに適用できます。たとえば、Controlオブジェクトのスタイルを作成し、それを複数のタイプのコントロール(Button、TextBox、CheckBoxなど)に適用できます。

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

スタイルを宣言するこれらの方法の両方があなたの質問に答えるかもしれないと思います。最初のものでは、TargetTypeは指定されていませんが、プロパティ名には「Label」というプレフィックスが付いています。 2番目の方法では、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>
36
Gaurang

TextblockとTextBoxにスタイルを適用したかったのですが、選択された回答はTextblockがControlから継承しないため機能しませんでした。この場合、Visibilityプロパティに影響を与えたいので、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}"/>

これは、Visibilityプロパティに対して機能します。これは、両方の項目がFrameworkelementから継承され、プロパティがそこで定義されているためです。もちろん、これはControlでのみ定義されたプロパティでは機能しません。階層ツリーを検索してベースクラスを見つけようとすることができます。とにかく、これはトップの検索結果であり、選択された答えが少し不完全なので、誰かに役立つと思いました.

4
The One

質問には別の答えがあります。 TargetTypeパラメーターをスタイルから完全に除外することができます。これにより、さまざまなコントロールに適用できるようになりますが、プロパティ名の前に「Control」を付ける場合のみです。

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

明らかに、これは基本コントロールクラスのプロパティに対してのみ機能します。 ItemsSourceを設定しようとした場合、Control.ItemsSourceがないため失敗します

3
PaulMolloy