2012-02-10 141 views
26

作爲標題,我的意思是類似下面:我可以在WPF中有一個具有多個TargetType的樣式嗎?

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

這實際上是使用第三方控制的緣故,我繼承了他們的階級。但該模板不適用於子類,因爲TargetType位於基類上。所以我想設置多個TargetType s使它能夠申請。

回答

45

不,你不能,但是我通常會創建一個樣式共享基類,如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}}" /> 
+1

不幸的是, FrameworkElement沒有包含很多屬性(比如與字體相關的屬性),所以它們不能包含在樣式設置器中。你可以選擇'ContentControl',但這不適用於這個特殊的例子,因爲TextBlock不會從ContentControl繼承。 – kmote 2017-02-09 17:50:40

2

答案是否定的。

TargetType是Style的屬性,只能設置一次。爲了確保類型安全,風格應該針對特定的類型,以便知道要設置的屬性。

但是,有一個解決辦法。您可以採用您擁有的所有類型的共同屬性,並將其定義爲一種樣式。然後爲每個特定控件製作特定的樣式,並使用BasedOn屬性繼承基本樣式。

0

其實我發現,在一網格只能設置一個項目的樣式。但是,在一個堆棧面板中,您可以設置多個項目的樣式。如果您要刪除其置於並更改爲你將看到的對象沒有設置,只有最後一個對象的屬性改變

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

看到這個代碼。

希望這會有所幫助。

8

Rachel答案的一個更靈活的變體是使用resourceKey for BasedOn。

代替

所以:

<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作爲目標類型。標記擴展中的類型,只是使用類型:

1

基於Rachel的答案,更清潔的代碼,你可以刪除X

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

是一樣的:

<Style TargetType="{x:Type Label}"> 
    <!-- Shared Setters --> 
</Style> 
相關問題