2011-08-17 12 views
5

Como pude ver, muchas personas se encontraron con este problema exacto, pero no puedo entender por qué mi caso no funciona y me está volviendo loco.Diseñando un Textblock autogenerado en un ContentPresenter

Contexto: Tengo un DataGrid que se va a colorear de acuerdo con los valores de cada celda. Por lo tanto, tengo un estilo dinámico que resuelve la plantilla real que se utilizará para cada celda. Los fondos ahora funcionan en consecuencia.

Problema nuevo: cuando tengo un fondo oscuro, quiero que el color de la fuente sea blanco y el peso de la fuente en negrita para que el texto sea legible correctamente. Y ... No puedo diseñarlo correctamente.

He leído algunos mensajes sobre Stackoverflow que:

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

Aquí es lo que he intentado hasta ahora:

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

no funciona. El fondo es verde, pero el texto permanece en negro & no negrita.

Por cierto, el BoldCellStyle es tan fácil como puede ser:

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

bien. Segundo intento (que es realmente estúpido, pero bueno ...)

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

No funciona tampoco.

Entonces, traté de jugar con las propiedades del ContentPresenter 's:

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

Y ... Como se puede esperar, esto no incluso trabajar.

Intrigado, utilicé Snoop para buscar todos los componentes de mi interfaz. En los dos primeros casos, Snoop realmente me muestra que cada celda es Grid con ContentPresenter que contiene TextBlock y Style real, pero ... Las propiedades de TextBlock no se aplican y FontWeight sigue siendo normal.

último caso, aún más chocante, puedo ver que Snoop me muestra que en realidad tenemos un ContentPresenter con las propiedades adecuadas (es decir TextElement.FontWeight="Bold"), pero el autogenerado TextBlock bajo es - todavía - no labrado.

No puedo obtener lo que me falta aquí. Intenté como puedes ver casi todo lo que podría hacer aquí, y el TextBlock s sigue sin formatearse.

¿Alguna idea aquí? ¡Gracias de nuevo!

Respuesta

2

El DataGridColumns que se derivan de DataGridBoundColumn (todos excepto DataGridTemplateColumn) tiene una propiedad ElementStyle que se aplica a la TextBlock cuando se crea. Por ej.DataGridTextColumn Parece que este

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

Se anula los metadatos para ElementStyle y proporciona un nuevo valor predeterminado, DefaultElementStyle, que, básicamente, sólo establece el margen predeterminado para el 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; 
    } 
} 

el estilo se define en el código cada vez que un nuevo DataGridCell se crea con element.Style = style; y esto es reemplazar el estilo que está tratando de establecer, incluso si se intenta establecer implícitamente.

Por lo que yo sé, que tendrá que repetir esto para sus columnas

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

Wow. ¿Estoy absolutamente obligado a hacer eso? El objetivo principal de mi trabajo aquí es estilizar cada celda por separado (algunas son en negrita, otras son normales) – Damascus

+0

@Damascus: Sí, hasta donde yo sé. Sin embargo, aún puede usar el mismo estilo, solo tiene que aplicarlo a cada columna. –

+0

Yo solo lo probé y "funciona" (sí, pone todas mis celdas en negrita), intentaré jugar con Triggers para hacerlo luego:/ – Damascus

Cuestiones relacionadas