2008-12-03 5 views
19

Ich binde eine Liste an eine DataGridView. Eine Eigenschaft der SomeObject-Klasse ist ein Statuscode (z. B. Rot, Gelb, Grün). Kann ich den Status einfach an die Hintergrundfarbe einer Zelle "binden"? Wie wäre es mit der Bindung an einen Tooltip?An DataGridView binden - Gibt es eine Möglichkeit, die Hintergrundfarbe einer Zelle zu "binden"?

+0

Ich hoffe wirklich, dass Sie eine Antwort darauf erhalten, und dass es möglich ist, konnte ich nicht herausfinden, dass ich die Hintergrundfarbe nach der Datenbindung durch Ändern der einzelnen Zellstil festlegen. Leider ist das wirklich langsam :(datagridview1.Rows [1] .Cells [2] .Style.BackColor = Color.Red –

Antwort

35

Sie können einen Handler für das CellFormatting-Ereignis von DataGridView schreiben, um die Hintergrundfarbe anzupassen. Hier ist ein ausgearbeitetes Beispiel (Sie benötigen einen Datagridview auf dem Standardformular gezogen haben dann auf dem Cellformatting-Ereignis doppelgeklickt einen Handler zu erstellen):

using System.Drawing; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class Form1 : Form 
    { 
     private BindingSource _source = new BindingSource(); 

     public Form1() 
     { 
      InitializeComponent(); 

      _source.Add(new MyData(Status.Amber, "Item A")); 
      _source.Add(new MyData(Status.Red, "Item B")); 
      _source.Add(new MyData(Status.Green, "Item C")); 
      _source.Add(new MyData(Status.Green, "Item D")); 

      dataGridView1.DataSource = _source; 
      dataGridView1.Columns[0].Visible = false; 
     } 

     private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
     { 
      if (e.ColumnIndex == 1) 
      { 
       DataGridView dgv = sender as DataGridView; 
       MyData data = dgv.Rows[e.RowIndex].DataBoundItem as MyData; 

       switch (data.Status) 
       { 
        case Status.Green: 
         e.CellStyle.BackColor = Color.Green; 
         break; 
        case Status.Amber: 
         e.CellStyle.BackColor = Color.Orange; 
         break; 
        case Status.Red: 
         e.CellStyle.BackColor = Color.Red; 
         break; 
       } 
      } 
     } 
    } 

    public class MyData 
    { 
     public Status Status { get; set; } 
     public string Text { get; set; } 

     public MyData(Status status, string text) 
     { 
      Status = status; 
      Text = text; 
     } 
    } 

    public enum Status 
    { 
     Green, 
     Amber, 
     Red 
    } 
} 

Die Objekte haben hier nur eine Zustands- und Text der Einfachheit halber . Ich erstelle eine BindingSource für eine Beispielmenge dieser Objekte und verwende diese dann als Datenquelle für die DataGridView. Standardmäßig generiert das Raster beim Binden automatisch Spalten, sodass Sie dies nicht manuell tun müssen. Ich verstecke auch die erste Spalte, die an den Status-Wert gebunden ist, da wir stattdessen die Textzellen färben werden.

Um tatsächlich zu malen, antworten wir auf das CellFormatting-Ereignis. Wir erhalten einen Verweis auf die DataGridView, indem wir den Sender übergeben und dann die RowIndex-Eigenschaft des DataGridViewCellFormattingEventArgs-Objekts verwenden, um das Datenelement selbst abzurufen (für jede Row gibt es eine DataBoundItem-Eigenschaft, die uns dies bequemerweise liefert). Da DataBoundItem ein Objekttyp ist, müssen wir ihn in unseren speziellen Typ umwandeln, dann können wir tatsächlich zur Status-Eigenschaft selbst gelangen ... puh!

Ich hatte keine Erfahrung mit der Tooltip-Programmierung, aber ich hätte gedacht, dass Sie auf das MouseHover-Ereignis reagieren sollten, und dann herausfinden, auf welche Zeile gerade hingewiesen wird.

Ich hoffe, das hilft.

+0

Schöne Antwort - danke. – xyz

+1

+1, große Antwort. Ich fand die letzte Zeile war eine leere Zeile, so musste überprüfen, ob MyData null war. Abgesehen davon, großartig! – Russell

+0

Das funktioniert gut, nur die Frage ist, ob es eine Möglichkeit gibt, diese Reihe zu einer Zeit statt einer Zelle zu machen 1000+ Zeilen, 10 + Spalten – Sint

2

Standardmäßig kann jede DataGridViewColumn nur an eine Eigenschaft der Objekte in der DataSource gebunden werden. Der Name der Eigenschaft wird vom DataPropertyName jeder DataGridViewColumn angegeben (Sie haben bestimmte Spaltentypen wie: DataGridViewTextBoxColumn, ...).

Sie können das DataGridView.CellFormatting-Ereignis verwenden, um den Stil der Zelle abhängig vom datengebundenen Element zu ändern. In der DataGridViewCellFormattingEventArgs dieses Ereignisses erhalten Sie den Zeilenindex, von dort können Sie das aktuelle Objekt (die Quelle der Zeile) abrufen. Von dort aus können Sie jede Eigenschaft des Objekts verwenden, um Ihre Zelle zu beeinflussen.

Ein guter Ausgangspunkt (ähnliche Idee): here

Eine zweite Idee wäre es Ihren eigenen Datagridviewcolumn-Typen entwickeln und Eigenschaften hinzufügen für andere Dinge, die Sie brauchen zu binden. Auf die gleiche Art und Weise wie der eingebaute DataPropertyName, können Sie Ihren eigenen hinzufügen: BackgroundColorPropertyName. Ein Startpunkt zum Erstellen von benutzerdefinierten DataGridViewColumns finden Sie here.