2010-09-08 16 views
9

J'ai un DataGrid lié aux données avec des couleurs d'arrière-plan de ligne en alternance. Je voudrais colorer une cellule différemment en fonction des données qu'elle contient. J'ai essayé la solution proposée par ce filWPF - Comment obtenir une cellule à partir d'un DataGridRow?

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

Mais,

DataGridCellsPresenter présentateur = GetVisualChild (ligne)

retourne toujours null.

J'utilise

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

Mais VisualTreeHelper.GetChildrenCount() d'un DataGridRow retourne toujours 0. J'ai vérifié que DataGridRow est non nul et a été remplie avec des données déjà. Toute aide est appréciée.

Merci.

Répondre

8

D'abord, ne le faites pas en code-behind. Vous combattez le cadre avec cette façon de faire les choses. WPF est conçu différemment; vous devez penser en termes de la façon dont le cadre veut que vous fassiez des choses. Dans le cas de WPF, il s'agit des classes XAML markup + converter.

Vous avez besoin de deux choses pour obtenir ce que vous voulez:

  • balisage XAML approprié pour configurer le style de la DataGrid
  • de mise en œuvre d'un IValueConverter pour traduire la valeur du texte en couleur de surlignage appropriée.

Ici va:

XAML dans votre Datagrid

La première chose que vous voulez faire est de définir le XAML nécessaire pour coiffer vos cellules DataGrid. Il ressemble à ceci:

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

Ce que cela fait est la mise en place d'une liaison au RelativeSource (le DataGridCell) et lui demander de changer la Content.Text de la cellule que la valeur de passer au convertisseur (dataGridCellConverter).

IValueConverter

La prochaine chose que vous avez besoin est une implémentation IValueConverter pour déterminer réellement les couleurs sur la base du texte de la cellule:

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(); 
    } 
    } 
} 

Ici, je suis à la recherche du texte "CMS" et colorant la cellule de fond; Si "CMS" n'existe pas, il renvoie la couleur orange à la place.

Précisez les ressources

Maintenant, vous devez ajouter des balises dans votre fenêtre/usercontrol pour spécifier le convertisseur comme une ressource appropriée:

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

Et cela devrait le faire! Bonne chance.

+0

+1 - réponse très détaillée – David

+3

'Dans le cas de WPF, il s'agit des classes XAML markup + converter.' - C'est vraiment votre perception personnelle –

11

Si vous connaissez votre ligne et l'index de la cellule que vous souhaitez accéder, puis voici comment vous pouvez le faire dans le code:

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

DataGrid Extension:

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

c'est la vraie réponse. –

+0

J'essaie quelque chose comme ça mais ça ne semble pas marcher. Pouvez-vous vérifier ce sujet http://stackoverflow.com/questions/32584353/wpf-control-datagrid-cell-color-change –

+1

C'est bien si vous ajoutez [méthodes] suivant (http://stackoverflow.com/a/25229554/2470362) à la réponse. –