2011-09-29 10 views
5

Non è insolito per me scrivere qualcosa di simile in basso per lo styling di un modulo di immissione dati, ma il mio problema è che e TextBlock non sembrano implementare i Setter che si trovano nello BaseElementStyle. Di solito ho bisogno di definirli separatamente.Perché il mio TextBlock/TextBox non applica i valori da uno stile di base?

Perché è questo? E c'è un modo per aggirarlo?

sto indovinando che ha a che fare con il fatto che di solito vengono utilizzati in altri modelli di controllo (ad esempio TextBlock è utilizzato nella maggior parte dei controlli e TextBox è utilizzato in datepickers e ComboBoxes)

<Style x:Key="BaseElementStyle" TargetType="{x:Type FrameworkElement}"> 
    <Setter Property="Margin" Value="5" /> 
    <Setter Property="VerticalAlignment" Value="Center" /> 
</Style> 
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseElementStyle}" /> 
<Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseElementStyle}" /> 
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseElementStyle}" /> 
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource BaseElementStyle}" /> 
<Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource BaseElementStyle}" /> 
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseElementStyle}" /> 

risposta

8

vorrei per suggerire i due possibili soluzioni. Sembra che sia possibile utilizzare ciascuna chiave e tipo, ma entrambe non possono essere utilizzate insieme come domanda, x:Key="BaseElementStyle" TargetType="{x:Type FrameworkElement}".

  1. usando x: Key

    <Style x:Key="BaseElementStyle"> 
        <Setter Property="FrameworkElement.Margin" Value="5" /> 
        <Setter Property="FrameworkElement.VerticalAlignment" Value="Center" /> 
    </Style> 
    <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseElementStyle}" /> 
    <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource BaseElementStyle}" /> 
    <Style TargetType="{x:Type Label}" BasedOn="{StaticResource BaseElementStyle}" /> 
    <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource BaseElementStyle}" /> 
    <Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource BaseElementStyle}" /> 
    <Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource BaseElementStyle}" /> 
    
  2. usando x: Tipo

    <Style TargetType="{x:Type FrameworkElement}"> 
        <Setter Property="Margin" Value="5" /> 
        <Setter Property="VerticalAlignment" Value="Center" /> 
    </Style> 
    <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource {x:Type FrameworkElement}}" /> 
    <Style TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" /> 
    <Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type FrameworkElement}}" /> 
    <Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" /> 
    <Style TargetType="{x:Type DatePicker}" BasedOn="{StaticResource {x:Type FrameworkElement}}" /> 
    <Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource {x:Type FrameworkElement}}" /> 
    
+0

Grazie! E mi hai insegnato qualcosa di nuovo ... non sapevo che avresti potuto basare uno stile su uno stile implicito come quello che hai mostrato al secondo. Molto bello sapere! – Rachel

7

Anche tenere a mente che WPF considera una ControlTemplate di essere un confine di inflazione e fa NON applicare gli stili predefiniti all'interno dei modelli. L'eccezione alla regola: tutto ciò che eredita da Controlsarà gonfiato con lo stile predefinito. Poiché lo TextBlock eredita da FrameworkElement e non da Control, se lo si utilizza all'interno di uno ControlTemplate, sarà necessario applicare manualmente lo stile. Questo vale sia per TextBlocks che vengono aggiunti manualmente, sia per TextBlocks aggiunto da WPF per la stringa Content. Un esempio veloce:

<Window x:Class="ImplicitStyles.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <StackPanel.Resources> 
      <Style x:Key="BaseElementStyle"> 
       <Setter Property="FrameworkElement.Tag" Value="Hello World" /> 
      </Style> 
      <Style TargetType="{x:Type Button}" BasedOn="{StaticResource BaseElementStyle}" /> 
      <Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseElementStyle}" /> 

      <!-- Default style for TextBlock will not be applied, Tag will be null --> 
      <ControlTemplate x:Key="MyContentControlTemplateOne" TargetType="{x:Type ContentControl}"> 
       <Border BorderBrush="Red" BorderThickness="2"> 
        <TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" /> 
       </Border> 
      </ControlTemplate> 

      <!-- Default style for Button will be applied, Tag will be Hello World -->  
      <ControlTemplate x:Key="MyContentControlTemplateTwo" TargetType="{x:Type ContentControl}"> 
       <Border BorderBrush="Red" BorderThickness="2"> 
        <Button Content="{Binding RelativeSource={RelativeSource Self}, Path=Tag}" /> 
       </Border> 
      </ControlTemplate> 

     </StackPanel.Resources> 

     <ContentControl Template="{StaticResource MyContentControlTemplateOne}" /> 
     <ContentControl Template="{StaticResource MyContentControlTemplateTwo}" /> 
    </StackPanel> 

</Window> 

Per ulteriori informazioni, vedere questo post del blog:

http://blogs.msdn.com/b/wpfsdk/archive/2009/08/27/implicit-styles-templates-controls-and-frameworkelements.aspx

+1

Grazie, non mi ero reso conto che i Templates fossero dei confini per l'ereditarietà dello stile. Mi stavo chiedendo perché TextBlocks all'interno di DataTemplates non ricevesse lo stesso stile applicato – Rachel