Problem mit Button in DataGridView
-
Hallo,
ich habe nach dem Befüllen des DataGridView (Win Forms) am Ende jeder Zeile einen Button eingefügt.
Nun möchte, dass wenn in der entsprechenden Spalte (also in der, in der sich der Button befindet) eine bestimmte Aktion ausgeführt wird.Es passiert aber nichts, beim Klick auf den Button, und mit dem Debugger habe ich gesehen, dass ColumnIndex immer 0 ist.
Was mache ich falsch?
Rufe ich eine falsche Methode auf?Füllen des Grid bzw. adden des Button
... DataGridViewButtonColumn btnSelect = new DataGridViewButtonColumn(); btnSelect.UseColumnTextForButtonValue = true; btnSelect.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; btnSelect.FlatStyle = FlatStyle.Standard; btnSelect.CellTemplate.Style.BackColor = Color.LightGray; btnSelect.Text = "Select"; btnSelect.HeaderText = "Change Group"; dgGroupMembership.Columns.Add(btnSelect);
Klick auf den Button
private void dgGroupMembership_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex == 5) { MessageBox.Show("Ausgewählt"); } }
Zuweisung des Click
this.dgGroupMembership.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(dgGroupMembership_CellClick);
-
Hallo Sonnenlichtfee,
wenn Du ein kompilierbares Minimalbeispiel(*) lieferst, beschäftige ich mich mit Deiner Problemstellung.
Das DGV ist komplex und kann vielfältig (fehl-)konfiguriert werden. Du ersparst Dir Zeit bis zu einer Lösung und den Antwortern Nerven, wenn ein kleines Minimalbeispiel gepostet wird. Vielleicht hast Du auch Glück und jemand kommt gleich mit der Lösung, aber häufig bleiben solche Fragen unbeantwortet.
(*) Mit 2 Minuten Aufwand per Copy & Paste in ein ausführbares Programm umzusetzen. Ohne externe Abhängigkeiten zu Datenbanken oder Dateien.
-
Hey,
das ist ziemlich einfach, Du kannst auf jedes Klick-Event reagieren,oder andere Events es muss dazu kein Button sein.
Hier ein kurzes Beispiel...
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { String anzeigeText; DataGridViewCell zelle = dataGridView1.Rows[e.RowIndex].Cells[2];//Übergibt den Wert der 3. Spalte und der aktuellen Zeile, wenn auf den Button in Spalte 6 geklickt wird: anzeigeText = zelle.FormattedValue.ToString(); if (e.ColumnIndex == 5)//Nur wenn auf die Button-Spalte gelickt wird, soll eine MessageBox ausgegeben werden: In diesem Beispiel liegen die Button in Spalte 5: { MessageBox.Show(anzeigeText); } }
In diesem Beispiel wird der Text der aktuellen Zeile und der 3. Spalte in einer MessageBox ausgegeben. So kannst Du jede Zeile und Spalte abfragen und auf die Ereignisse reagieren.
Ich hoffe das hilft Dir!?
Gruß
Doug_HH
-
@µ
Anbei ein Beispiel, hat wegen verlängertem WE etwas gedauert ... nur dass da alles (= MessageBox wird angezeigt; sowie farbige Markierung der Zelle) gemacht wird.
Nur in meinem eigentlich Projekt, welches an die DB gebunden ist, klappt das nicht (=ColumnIndex ist immer 0).namespace DGV_Test { public partial class Form1 : Form { public Form1() { InitializeComponent(); SetupGrid(); FillGrid(); } private void SetupGrid() { dataGridView1.Columns.Add("Spalte1", "Datum"); dataGridView1.Columns.Add("Spalte2", "Lfd. Nummer"); dataGridView1.Columns.Add("Spalte3", "Nummer"); DataGridViewButtonColumn btnSelect = new DataGridViewButtonColumn(); btnSelect.UseColumnTextForButtonValue = true; btnSelect.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; btnSelect.FlatStyle = FlatStyle.Standard; btnSelect.CellTemplate.Style.BackColor = Color.LightGray; btnSelect.Text = "Select"; btnSelect.HeaderText = "Change"; dataGridView1.Columns.Add(btnSelect); } private void FillGrid() { string[] row0 = { "20.05.2012", "29", "SCN-3201-2" }; string[] row1 = { "02.06.2011", "9", "SCN-1293-6" }; string[] row2 = { "11.11.2011", "1", "SCN-3204-2" }; string[] row3 = { "18.05.2012", "6", "SGN-5421-2" }; string[] row4 = { "17.05.2012", "7", "WGN-8721-5" }; string[] row5 = { "06.10.2012", "13","WGN-6122-5" }; string[] row6 = { "26.03.2010", "3", "WGN-6123-5" }; dataGridView1.Rows.Add(row0); dataGridView1.Rows.Add(row1); dataGridView1.Rows.Add(row2); dataGridView1.Rows.Add(row3); dataGridView1.Rows.Add(row4); dataGridView1.Rows.Add(row5); dataGridView1.Rows.Add(row6); } private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { if (e.ColumnIndex == 3) { MessageBox.Show("Ausgewählt"); dataGridView1[1, e.RowIndex].Style.BackColor = Color.Red; } } } }
Können die Probleme daran liegen, wie die Daten an das DGV gebunden werden?
Oder welche Ursache kann das haben?
-
@Doug_HH
Danke für den Tipp ... Problem bei mir ist allerdings, dass der ColumnIndex nie einen anderen Wert als 0 erhält - warum auch immer?!
-
Sonnenlichtfee schrieb:
Danke für den Tipp ... Problem bei mir ist allerdings, dass der ColumnIndex nie einen anderen Wert als 0 erhält - warum auch immer?!
Kann eigentlich nicht sein, da Du den Wert über DataGridViewCellEventArgs e bekommst.
Lass doch mal den Wert über eine MessageBox ausgeben.
In...
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { MessageBox.Show("Spalte: " + e.ColumnIndex.ToString() + " Zeile: " + e.RowIndex.ToString()); }
Gibt danach nochmal Meldung...
Gruß
-
Danke für den Tipp ...
Folgendes Ergebnis:
Klicke ich auf die Spalte, die den Button enthält, ist ColumnIndex = 0. Der RowIndex ist immer richtig.
Klicke ich dagegen auf irgend eine Zelle, so wird auch der richtige ColumnIndex ausgegeben.private void dgGroupMembership_CellClick(object sender, DataGridViewCellEventArgs e) { MessageBox.Show("Spalte: " + e.ColumnIndex.ToString() + " Zeile: " + e.RowIndex.ToString()); }
Wird der Button nicht "erkannt", oder an was liegt das?
Der andere Problemfall ist noch der, dass wenn das GDV befüllt wird (auch ohne Button), es nicht möglich ist, bestimmte Zellen (oder Spalte) farbig zu hinterlegen.
dgGroupMembership[1, 5].Style.BackColor = Color.AliceBlue;
-
Kann ich mir nicht erklären, kannst Du vielleicht ein Vergleichsprojekt schicken!?
-
Anbei mal der Code aus meinem Projekt.
In der ersten Datei rufe ich die Methode zum Befüllen und zur Formatierung des DGV auf.
Tasks.csnamespace Orders { public partial class frmOrders : Form { public frmOrders() { InitializeComponent(); FillGridOrders(); dgOrdersProduction[2, 4].Style.BackColor = Color.Red; // in dem Bereich habe ich auch schon einen Button an den DGV // angehängt, welcher dann beim Klicken immer ColumnIndex = 0 hat } private void FillGridOrders() { dgOrdersProduction.DataSource = DB.GetProductionOrderTasks(); } ... }
Der Datenbankzugriff, um die Daten in eine DataTable einzulesen und zu übergeben.
DB.cspublic static DataTable GetProductionOrderTasks() { using (var connection = new MySqlConnection(conString)) { string sDeliveryDate = System.DateTime.Today.AddDays(-2).ToString(); string sParsedDeliveryDate = DateTime.ParseExact(sDeliveryDate, "dd.MM.yyyy HH:mm:ss", new CultureInfo("de-DE")).ToString("yyyy-MM-dd"); connection.Open(); var stringBuilder = new StringBuilder(); stringBuilder.Append("SELECT ... "); stringBuilder.Append("WHERE tblOrderdetails.date > '" + sParsedDeliveryDate + "' "); ... String query = stringBuilder.ToString(); using (var command = new MySqlCommand(query, connection)) { var da = new MySqlDataAdapter(); da.SelectCommand = command; DataTable dt = new DataTable(); da.Fill(dt); return dt; } } }
Vielleicht hilft das ja weiter?!?!
Jedenfalls kann ich mit der Art und Weise weder einen Button sinnvoll nutzen (was aber für den User schöner wäre) noch eine farbige Hinterlegung machen.
-
Lade Dir mal dieses Bsp. Projekt runter, geschrieben in 2010.
Vergleiche das mal mit Deinem Code.www.rb-softarticle.com/DGVBsp.rar
Gruß
-
@Doug_HH
Danke für Deine Hilfe!!Ich habe jetzt folgende Lösung gefunden:
Anstatt einer DataTable binde ich ein DataSet an das DataGridView. Siehe da, die Zeilen werden farbig und der Spaltenindex wird richtig erkannt.Warum das mit einem DataSet geht und mit einer DataTable weiß ich zwar nicht, aber vorerst bin ich einfach mal glücklich damit, dass ich endlich zum gewünschten Ergebnis komme.
Falls jemand eine Erklärung dafür hat, ich würde mich über eine Antwort freuen!
Danke!