2009-05-21 4 views
3

habe ich ein Programm, in dem ich die Daten der Grid-Ansicht manuell aktualisieren wollte. -Ich habe eine Methode zum Aktualisieren der DGV, indem Sie sie löschen und dann die Daten erneut einfügen. - Mit dem Designer habe ich einen Event-Handler für den CellEndEdit des DGV erstellt. Im Ereignishandler werden die Daten aktualisiert & der DGV die benutzerdefinierte Auffrischungsmethode aufgerufen wird.InvalidOperationException - Beim Bearbeiten einer Zelle endet & Umzug in eine andere Zelle

Während das Programm läuft, wenn ich eine Zelle & Ende es Bearbeitung starten durch eine andere Auswahl, wird eine Ausnahme ausgelöst:

InvalidOperationException Betrieb nicht gültig ist, weil es in einem einspringenden Aufruf der SetCurrentCellAddressCore Funktion führt.

Visual C# 's Debugger markiert die Zeile, die die Daten löscht: datagridview1.Rows.Clear();

Wenn Sie möchten, das Problem reproduzieren, Machen Sie ein neues Windows-Formular-Projekt mit Visual C#, ein Datagridview-Objekt auf dem Formular platzieren, und fügen Sie den folgenden Code für das Form1.cs:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 

namespace Error___DataGridView_Updating___Cell_endedit 
{ 
    public partial class Form1 : Form 
    { 
     // Objects 
     DataTable dt; 
     DataColumn colID; 
     DataColumn colName; 
     DataColumn colInfo; 
     // Constructor 
     public Form1() 
     { 
      InitializeComponent(); 

      Initialize_dt(); 
      InsertSampleData_dt(); 
      Initialize_dataGridView1(); 
     } 

     // Methods 
     private void Initialize_dt() 
     { 
      dt = new DataTable(); 

      // Building Columns 
      // ID 
      colID = new DataColumn(); 
      colID.ColumnName = "ID"; 
      colID.DataType = typeof(int); 
      dt.Columns.Add(colID); 

      // Name 
      colName = new DataColumn(); 
      colName.ColumnName = "Name"; 
      colName.DataType = typeof(string); 
      dt.Columns.Add(colName); 

      //Info 
      colInfo = new DataColumn(); 
      colInfo.ColumnName = "Info"; 
      colInfo.DataType = typeof(string); 
      dt.Columns.Add(colInfo); 
     } 

     private void InsertSampleData_dt() 
     {    
      DataRow row; 

      // 0 
      row = dt.NewRow(); 
      row["ID"] = 100; 
      row["Name"] = "AAAA"; 
      row["Info"] = "First Record"; 
      dt.Rows.Add(row); 

      //1 
      row = dt.NewRow(); 
      row["ID"] = 101; 
      row["Name"] = "BBBB"; 
      row["Info"] = "Second Record"; 
      dt.Rows.Add(row); 


      //2 
      row = dt.NewRow(); 
      row["ID"] = 102; 
      row["Name"] = "CCCC"; 
      row["Info"] = "Third Record"; 
      dt.Rows.Add(row); 
     } 

     private void Initialize_dataGridView1() 
     { 
      dataGridView1.AllowUserToAddRows = false; 

      // Data Grid Definitions 
      //  Row Header 

      dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.DisableResizing; 
      dataGridView1.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; 
      //  ColumnHeaders 
      dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; 

      // Building Columns 
      #region ID 
      { 
       DataGridViewColumn colSGID = new DataGridViewTextBoxColumn(); 
       colSGID.Name = "ID"; 
       colSGID.HeaderText = "#"; 
       colSGID.ReadOnly = true; 
       colSGID.Visible = false; 
       colSGID.Resizable = DataGridViewTriState.False; 

       dataGridView1.Columns.Add(colSGID); 
      } 
      #endregion 

      #region Name 
      { 
       DataGridViewColumn colSGName = new DataGridViewTextBoxColumn(); 
       colSGName.Name = "Name"; 
       colSGName.HeaderText = "Name"; 

       dataGridView1.Columns.Add(colSGName); 
      } 
      #endregion 

      #region Info 
      { 
       DataGridViewColumn colSGSubject = new DataGridViewTextBoxColumn(); 
       colSGSubject.Name = "Info"; 
       colSGSubject.HeaderText = "Description"; 

       dataGridView1.Columns.Add(colSGSubject); 
      } 
      #endregion 

      Refresh_dataGridView1(); 
     } 

     private void Refresh_dataGridView1() 
     { 
      int index; 

      dataGridView1.SuspendLayout(); 

      dataGridView1.Rows.Clear(); 

      //MessageBox.Show("Cleared Data. Rebuilding..."); 

      foreach (DataRow row in dt.Rows) 
      { 
       index = dataGridView1.Rows.Add(new DataGridViewRow()); 

       dataGridView1.Rows[index].Cells["ID"].Value = row["ID"]; 
       dataGridView1.Rows[index].Cells["Name"].Value = row["Name"]; 
       dataGridView1.Rows[index].Cells["Info"].Value = row["Info"]; 

       //MessageBox.Show("row #" + index); 
      } 

      dataGridView1.ResumeLayout(); 
     } 

     //Event Handlers 
     private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
     { 
      bool toUpdate = false; 

      int id = (int)dataGridView1.Rows[e.RowIndex].Cells["ID"].Value; 
      string columnName = dataGridView1.Columns[e.ColumnIndex].Name; 
      string value = (string)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; 

      if (value == null) 
      { 
       value = string.Empty; 
      } 

      switch (columnName) 
      { 
       case "Name": 
        if (value == string.Empty) 
        { 
         MessageBox.Show("Name Can't Be Empty!"); 
        } 
        else 
        { 
         toUpdate = true; 
        } 
        break; 
       case "Info": 
        toUpdate = true; 
        break; 
      } 

      if (toUpdate) 
      { 
       foreach(DataRow row in dt.Rows) 
       { 
        if ((int)row["ID"] == id) 
        { 
         row[columnName] = value; 
        } 
       } 

       Refresh_dataGridView1(); 
      } 

     } 
    } 
} 
+0

Vergessen zu erwähnen. Führen Sie nach dem Einfügen des Codes das Programm aus und gehen Sie folgendermaßen vor: 2) klicken Sie auf eine Zelle (wählen Sie sie aus). 3) Klicken Sie erneut auf diese Zelle (Sie gelangen in den Bearbeitungsmodus). 4) Wählen Sie eine andere Zelle (das Ereignis cell end edit tritt auf, Ausnahme sollte jetzt ausgelöst werden). –

+0

Ich habe dein Problem verstanden ... aber ich verstehe nicht, was du erreichen willst ... bitte sei etwas ausführlicher. Soweit ich das verstehen kann, versuchen Sie den Zellenwert zu aktualisieren ... habe ich recht ...? –

+0

Ja, ich versuche, den Zellenwert in der Datentabelle mithilfe der Datenrasteransicht * zu aktualisieren. Ich "binde" manuell die Datenrasteransicht, damit ich mehr Kontrolle darüber haben kann, welche Werte erlaubt oder nicht erlaubt sind. (* In meinem eigentlichen „Projekt“, aber ich bin der Aktualisierung eines typisierten Datensatz einen Tisch-Adapter) –

Antwort

6

Es gibt eine Antwort von Bruce.Zhou auf MSDN-Foren. Ich habe hier einen Ausschnitt veröffentlicht. Here ist auch der Link zum ursprünglichen Beitrag.

private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
{ 
    ...................................................; 
    if (toUpdate) 
    { 
     foreach(DataRow row in dt.Rows) 
     { 
      if ((int)row["ID"] == id) 
      { 
       row[columnName] = value; 
      } 
     } 

     this.BeginInvoke(new MethodInvoker(Refresh_dataGridView1)); 
    } 
} 

...

Wenn dieses Update verwenden, wann immer die neue Zelle ausgewählt wird, werden alle Zellen zwischen ihr und der ersten Zelle (einschließlich) ausgewählt. Ich suche nach einer Möglichkeit, nur die neue Zelle auszuwählen.

1

i schlug meinen Kopf gegen die Tastatur für die letzte Stunde, dieses Problem zu lösen. hier ist meine Abhilfe: auf das Problem suchen: wenn eine andere Zelle (oder eine Kontrolle innerhalb der gridview) EndEdit ausgelöst Auswahl.

gelten die folgenden Kontrolle vor der Bearbeitung Anwendung:

public void myGrid_EndEdit(object sender, DataGridViewCellEventArgs e) 
{ 
    if (!myGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Selected) 
       return; 
    //...rest of your code to apply edit below... 
} 

Diese auf eine beliebige Zelle bearbeitet gelten sollte (also bearbeiten nicht angewendet wird, wenn der Fokus zu verlieren; Typing würde genügen Geben Sie den Bearbeitungs anzuwenden)

.
0

Meine Arbeit um war das CellMouseDown Ereignis zu erfassen, und wenn die Aktion auf einer anderen Zelle war als die gerade bearbeitet wird, dann gibt es die DataGridView.EndEdit(). Alles andere funktioniert wie erwartet.

Verwandte Themen