2011-08-17 14 views
5

Come ho visto, un sacco di persone si sono imbattuti in questo problema esatto ma non riesco a capire perché il mio caso non funzioni e sta iniziando a farmi impazzire.Styling di un blocco di testo generato automaticamente in ContentPresenter

Contesto: Ho un DataGrid che deve essere colorato in base ai valori di ciascuna cella. Quindi, ho uno stile dinamico che risolve il modello reale da utilizzare per ogni cella. Gli sfondi ora funzionano di conseguenza.

Nuovo problema: quando ho uno sfondo scuro, voglio che il colore del font sia bianco e che il peso del font sia in grassetto così che il testo sia correttamente leggibile. E ... non riesco a farlo in modo corretto.

Ho letto alcuni post StackOverflow su che:

This one fits my problem but doesn't provide me any working solution This one is also clear and detail but... duh This is almost the same problem as me but... Solution does not work

Ecco quello che ho provato finora:

<!-- Green template--> 
    <ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}"> 
     <Grid Background="Green"> 
      <ContentPresenter 
          HorizontalAlignment="Center" 
             VerticalAlignment="Center"> 
       <ContentPresenter.Resources> 
        <Style BasedOn="{StaticResource BoldCellStyle}" TargetType="{x:Type TextBlock}" /> 
       </ContentPresenter.Resources> 
      </ContentPresenter> 
     </Grid> 
    </ControlTemplate> 

non funziona. Lo sfondo è verde, ma il testo rimane in nero & non in grassetto.

BTW, il BoldCellStyle è così facile come può essere:

<Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}"> 
    <Setter Property="FontWeight" Value="Bold"/> 
    <Setter Property="Foreground" Value="White" /> 
</Style> 

Va bene. Secondo tentativo (che è un vero e proprio uno stupido, ma ben ...)

<!-- Green template --> 
    <ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}"> 
     <Grid Background="Green"> 
      <ContentPresenter 
          HorizontalAlignment="Center" 
             VerticalAlignment="Center"> 
       <ContentPresenter.Resources> 
        <Style x:Key="BoldCellStyle" TargetType="{x:Type TextBlock}"> 
         <Setter Property="FontWeight" Value="Bold"/> 
         <Setter Property="Foreground" Value="White" /> 
        </Style> 

       </ContentPresenter.Resources> 
      </ContentPresenter> 
     </Grid> 
    </ControlTemplate> 

non funziona neanche.

Poi, ho provato a giocare con le proprietà 's il ContentPresenter:

<!-- Green template --> 
<ControlTemplate x:Key="Green" TargetType="{x:Type tk:DataGridCell}"> 
    <Grid Background="Green"> 
     <ContentPresenter TextElement.FontWeight="Bold" TextElement.Foreground="White" TextBlock.Foreground="White" 
         HorizontalAlignment="Center" 
            VerticalAlignment="Center" /> 
    </Grid> 
</ControlTemplate> 

E ... Come ci si può aspettare, questo non funziona nemmeno.

Incuriosito, ho usato Snoop per sfogliare tutti i componenti della mia interfaccia. Nei primi due casi, Snoop mi mostra effettivamente che ogni cella è un Grid con un ContentPresenter contenente un TextBlock e l'effettivo Style ma ... Le proprietà di TextBlock non si applicano e FontWeight è ancora normale.

Ultimo caso, ancora più scioccante, mi rendo conto che Snoop mi dimostra che in realtà abbiamo un ContentPresenter con le giuste proprietà (cioè TextElement.FontWeight="Bold"), ma il generata automaticamente TextBlock sotto è - ancora - non stile.

Non riesco a ottenere quello che mi manca qui. Ho provato come puoi vedere quasi tutto quello che potrei fare qui, e gli TextBlock continuano a non essere formattati.

Qualche idea qui? Grazie ancora!

risposta

2

Il DataGridColumns che derivano da DataGridBoundColumn (tutti tranne DataGridTemplateColumn) presenta una struttura ElementStyle che viene applicata al TextBlock quando viene creato. Ad es.DataGridTextColumn Sembra che questo

static DataGridTextColumn() 
{ 
    ElementStyleProperty.OverrideMetadata(typeof(DataGridTextColumn), 
     new FrameworkPropertyMetadata(DefaultElementStyle)); 
    // ... 
} 

Esso sovrascrive i metadati per ElementStyle e fornisce un nuovo valore di default, DefaultElementStyle, che fondamentalmente solo imposta il margine di default per il TextBlock.

public static Style DefaultElementStyle 
{ 
    get 
    { 
     if (_defaultElementStyle == null) 
     { 
      Style style = new Style(typeof(TextBlock)); 
      // Use the same margin used on the TextBox to provide space for the caret 
      style.Setters.Add(new Setter(TextBlock.MarginProperty, new Thickness(2.0, 0.0, 2.0, 0.0))); 
      style.Seal(); 
      _defaultElementStyle = style; 
     } 
     return _defaultElementStyle; 
    } 
} 

Questo stile è impostato nel codice ogni volta che un nuovo DataGridCell viene creato con element.Style = style; e questo è prevalente lo stile si sta cercando di impostare, anche se si cerca di impostare in modo implicito.

Per quanto ne so, dovrete ripetere questo per le colonne

<DataGridTextColumn Header="Column 1" ElementStyle="{StaticResource BoldCellStyle}" .../> 
<DataGridTextColumn Header="Column 2" ElementStyle="{StaticResource BoldCellStyle}" .../> 
+0

Wow. Sono assolutamente costretto a farlo? Lo scopo principale del mio lavoro qui è quello di personalizzare ogni cella separatamente (alcune sono in grassetto, altre sono normali) – Damascus

+0

@Damascus: Sì, per quanto ne so. Puoi comunque usare lo stesso stile, devi solo applicarlo a ogni colonna. –

+0

Ho appena provato e funziona "(sì, imposta tutte le mie celle in grassetto), proverò a giocare con Triggers per renderlo poi:/ – Damascus

Problemi correlati