2010-09-08 16 views
9

Tengo un DataGrid enlazado a datos con colores de fondo de fila alternativos. Me gustaría colorear una celda de forma diferente en función de los datos que contiene. He intentado la solución sugerida por este hiloWPF - ¿Cómo obtener una celda de un DataGridRow?

http://wpf.codeplex.com/Thread/View.aspx?ThreadId=51143

Pero,

DataGridCellsPresenter presentador = GetVisualChild (fila)

siempre devuelve un valor nulo.

estoy usando

public static T GetVisualChild<T>(Visual parent) where T : Visual 
    { 
     T child = default(T); 
     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 

Pero VisualTreeHelper.GetChildrenCount() de un DataGridRow siempre devuelve 0. He comprobado que DataGridRow no es nulo y se ha rellenado con los datos ya. Cualquier ayuda es apreciada.

Gracias.

Respuesta

8

Lo primero es lo primero, no haga esto en código subyacente. Estás luchando contra el marco con esta forma de hacer las cosas. WPF está diseñado de manera diferente; tienes que pensar en términos de cómo el marco quiere que hagas cosas. En el caso de WPF, se trata de las clases XAML markup + converter.

se necesitan dos cosas para lograr lo que quiere:

  • apropiado marcado XAML para configurar el estilo de la cuadrícula de datos
  • aplicación Un IValueConverter para traducir el valor del texto en color de realce adecuado.

aquí va:

XAML en su cuadrícula de datos

La primera cosa que quiero hacer es definir el XAML necesario para el estilo de sus células DataGrid. Se ve así:

<toolkit:DataGrid.CellStyle> 
     <Style TargetType="{x:Type toolkit:DataGridCell}"> 
     <Style.Setters> 
      <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content.Text, Converter={StaticResource dataGridCellConverter}}" /> 
     </Style.Setters> 
     </Style> 
    </toolkit:DataGrid.CellStyle> 

Lo que esto hace es la creación de una unión a la RelativeSource (el DataGridCell) y diciéndole que la utilice el Content.Text de la célula como el valor para pasar al convertidor (dataGridCellConverter)

IValueConverter

La próxima cosa que necesita es una implementación IValueConverter para determinar realmente los colores basados ​​en el texto de la celda:

using System; 
using System.Globalization; 
using System.Windows.Data; 
using System.Windows.Media; 
namespace UserControls.Utility.Converters 
{ 
    public class DataGridCellConverter : IValueConverter 
    { 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) return Colors.White.ToString(); 

     if (value.ToString().ToUpper().Contains("CMS")) return "LIME"; 

     return "ORANGE"; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
    } 
} 

Aquí, sólo estoy buscando el texto "CMS" y coloreando la celda de fondo; si "CMS" no existe, entonces devuelve el color naranja en su lugar.

Especificar Recursos

Ahora, es necesario añadir marcado en la ventana/control de usuario para especificar el convertidor como un recurso adecuado:

<UserControl.Resources> 
    <Converters:DataGridCellConverter x:Key="dataGridCellConverter"/> 
</UserControl.Resources> 

y que debe hacerlo! Buena suerte.

+0

+1 - respuesta muy detallada – David

+3

'En el caso de WPF, es XAML marcado + clases de conversión.' - esta es tu opinión personal muy –

11

Si sabe que su índice de fila y de la célula desea acceder, entonces aquí es cómo puede hacerlo en código: Extensión

//here's usage 
var cell = myDataGrid.GetCell(row, columnIndex); 
if(cell != null) 
    cell.Background = Brushes.Green; 

cuadrícula de datos:

public static class DataGridExtensions 
{ 
    public static DataGridCell GetCell(this DataGrid grid, DataGridRow row, int columnIndex = 0) 
    { 
     if (row == null) return null; 

     var presenter = row.FindVisualChild<DataGridCellsPresenter>(); 
     if (presenter == null) return null; 

     var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); 
     if (cell != null) return cell; 

     // now try to bring into view and retreive the cell 
     grid.ScrollIntoView(row, grid.Columns[columnIndex]); 
     cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); 

     return cell; 
    } 
+1

esa es la verdadera respuesta. –

+0

Estoy intentando algo así pero parece que no funciona. Puedes consultar este tema http://stackoverflow.com/questions/32584353/wpf-control-datagrid-cell-color-change –

+1

Es bueno si agregas los siguientes [métodos] (http://stackoverflow.com/a/25229554/2470362) a la respuesta. –

Cuestiones relacionadas