web-dev-qa-db-ja.com

WPFで複数のTargetTypeを持つ1つのスタイルを持つことはできますか?

タイトルのとおり、私は以下のようなものを意味します:

<Style TargetType="{x:Type TextBlock}" 
       TargetType="{x:Type Label}"  
       TargetType="{x:Type Button}" >

これは実際にはサードパーティのコントロールを使用するためのものであり、私はそれらのクラスを継承しています。ただし、TargetTypeは基本クラスにあるため、テンプレートはサブクラスには適用されません。そこで、両方に適用できるように、複数のTargetTypeを設定したいと思います。

30
King Chan

いいえ、できません。ただし、FrameworkElementなどの共有基本クラスのスタイルを作成してから、基本スタイルBasedOnである個別のコントロールスタイルを作成することがよくあります。

<Style TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>

<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />
51
Rachel

レイチェルの答えのより柔軟なバリエーションは、BasedOnにresourceKeyを使用することです。

したがって、代わりに:

<Style TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" />


次のようなことを行います。

<Style x:Key="commonStyle" TargetType="{x:Type FrameworkElement}">
    <!-- Shared Setters -->
</Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource commonStyle}" />


これにより、一部のスタイルはcommonStyleに基づくことができ、一部のスタイルはたとえばcommonStyle2。ここで、commonStyleとcommonStyle2の両方がターゲットタイプとしてFrameworkElementを持っています。

8
alterfox

レイチェルの答えに基づいて、よりクリーンなコードのために、マークアップ拡張内のx:Typeを削除し、Type:

<Style TargetType="Label">
    <!-- Shared Setters -->
</Style>

と同じです:

<Style TargetType="{x:Type Label}">
    <!-- Shared Setters -->
</Style>
2
lowry0031

答えはノーです。

TargetTypeはStyleのプロパティであり、一度だけ設定できます。タイプの安全性を保証するために、スタイルは、設定するプロパティを知るために特定のタイプをターゲットにする必要があります。

ただし、回避策があります。あなたが持っているすべてのタイプの共通のプロパティを取り、それらを1つのスタイルで定義することができます。次に、特定のコントロールごとに特定のスタイルを作成し、 BasedOn プロパティを使用して基本スタイルから継承します。

2
Sofian Hnaide

実際、グリッドでは1つのアイテムのスタイルしか設定できないことがわかりました。ただし、スタックパネルでは、複数のアイテムのスタイルを設定できます。

このコードを参照してください:

<Grid>        
    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="FontSize" Value="12"></Setter>
                <Setter Property="VerticalAlignment" Value="Center"></Setter>
                <Setter Property="HorizontalAlignment" Value="Center"></Setter>
                <Setter Property="Margin" Value="5"></Setter>
            </Style>
            <Style TargetType="TextBox">
                <Setter Property="Width" Value="100"></Setter>
                <Setter Property="Height" Value="25"></Setter>
                <Setter Property="Margin" Value="5"></Setter>
            </Style>
            <Style TargetType="Button">
                <Setter Property="Margin" Value="5"></Setter>
                <Setter Property="Height" Value="30"></Setter>
                <Setter Property="Width" Value="100"></Setter>
            </Style>
        </StackPanel.Resources>
        <StackPanel Orientation="Horizontal">
            <TextBlock>Kanban ID</TextBlock>
            <TextBox></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock>Customer Name</TextBlock>
            <TextBox></TextBox>
        </StackPanel>            
        <Button>Save</Button>
    </StackPanel>
</Grid>

その下の場所を削除して変更すると、オブジェクトが設定されていないことがわかり、最後のオブジェクトのプロパティのみが変更されます。

お役に立てれば。

0
Pat