webentwicklung-frage-antwort-db.com.de

Auslösen eines Checkbox-Wert-Änderungsereignisses in DataGridView

Ich habe eine Rasteransicht, die eine Kontrollkästchen-Spalte hat, und ich möchte ein Zeichnungsereignis auslösen, sobald der Wert der Zelle umgeschaltet wird. Ich habe das ValueChaged und das CellEndEdit und das BeginEdit ausprobiert und den Auswahlmodus als CellSelect ausgewählt. Bei den ersten beiden Ereignissen wurde das Ereignis ausgelöst, wenn der Bearbeitungsmodus beendet wurde, z. B. das Verlassen der aktuellen Zelle oder das Vor- und Zurückgehen. Es ist nur ein komisches Verhalten. 

Gibt es etwas, das das Ereignis in der Rasteransicht auslöst, sobald der Zellenwert geändert wird?

Freundliche Grüße,

29
mustafabar

Ein Kollege von mir empfiehlt, das CurrentCellDirtyStateChanged-Ereignis abzufangen. Siehe http://msdn.Microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx

23
user120381

Ich verwende das CellContentClick-Ereignis, um sicherzustellen, dass der Benutzer das Kontrollkästchen aktiviert hat. Es wird mehrmals ausgelöst, auch wenn der Benutzer in derselben Zelle bleibt. Das eine Problem ist, dass der Wert nicht aktualisiert wird und immer "false" für ungeprüft zurückgibt. Der Trick besteht darin, die .EditedFormattedValue-Eigenschaft der Zelle anstelle der Value-Eigenschaft zu verwenden. Der EditedFormattedValue verfolgt das Häkchen und ist der Wunsch des Werts, wenn der CellContentClick ausgelöst wird.

Es ist kein Timer erforderlich, kein ausgefallenes Zeug. Verwenden Sie einfach das CellContentClick-Ereignis, und überprüfen Sie den EditedFormattedValue, um festzustellen, in welchem ​​Status sich das Kontrollkästchen befindet. Wenn EditedFormattedValue = true ist, wird das Kontrollkästchen aktiviert.

32
Christo

Eine andere Möglichkeit besteht darin, das CellContentClick-Ereignis (das den aktuellen Wert in der Value-Eigenschaft der Zelle nicht angibt) zu behandeln. Rufen Sie grid.CommitEdit (DataGridViewDataErrorContexts.Commit) auf, um den Wert zu aktualisieren, der CellValueChanged abruft, wo Sie dann den Wert abrufen können tatsächlicher (dh richtiger) DataGridViewCheckBoxColumn-Wert.

private void grid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
   grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

private void grid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // do something with grid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value
}

Ziel-.NET-Framework: 2.0

20
Stuart

Ich hatte das gleiche Problem, kam aber zu einer anderen Lösung:

Wenn Sie die Spalte oder das gesamte Raster als "schreibgeschützt" festlegen, ändert der Wert nicht, wenn der Benutzer auf das Kontrollkästchen klickt.

Glücklicherweise ist das DataGridView.CellClick-Ereignis immer noch ausgelöst ..__ In meinem Fall mache ich Folgendes im cellClick-Ereignis:

if (jM_jobTasksDataGridView.Columns[e.ColumnIndex].CellType.Name == "DataGridViewCheckBoxCell")

Sie können jedoch den Spaltennamen überprüfen, wenn Sie mehr als eine Checkbox-Spalte haben.

Die gesamte Änderung/Speicherung des Datensatzes erledige ich dann selbst.

4
James

Kleines Update .... Stellen Sie sicher, dass Sie EditedFormattedValue anstelle von value verwenden, da ich value ausprobiert habe. Es wird jedoch nie der richtige Status angegeben, der aktiviert/deaktiviert ist. Die meisten Seiten der Site verwenden zwar value, aber wie in letzter Version c # 2010 express verwendet ein Weg, um zuzugreifen ..

grdJobDetails.Rows[e.RowIndex].Cells[0].EditedFormattedValue

Auch das _CellValueChanged-Ereignis, das von wenigen vorgeschlagen oder verwendet wird, muss für einige Fälle brauchbar sein. Wenn Sie jedoch nach jeder Überprüfung/Deaktivierung der Zelle suchen, stellen Sie sicher, dass Sie _CellContentClick verwenden. Andernfalls sehe ich nicht jedes Mal, wenn _CellValueChanged ausgelöst wird Das Kontrollkästchen wird immer wieder angeklickt. Es wird nicht _CellValueChanged ausgelöst. Wenn Sie jedoch abwechselnd klicken, haben Sie zwei Chekbox-Optionen und klicken Sie nacheinander auf _CellValueChanged. Das Ereignis wird ausgelöst. In der Regel wird jedoch nach einem Ereignis gesucht, das ausgelöst wird, wenn die Zelle _CellValueChanged aktiviert/deaktiviert ist. wird nicht abgefeuert.

4
user593029

Ich habe es schließlich so umgesetzt

  private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {

        if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
        {
            if (dataGridView1[e.ColumnIndex, e.RowIndex].GetContentBounds(e.RowIndex).Contains(e.Location))
            {
                cellEndEditTimer.Start();
            }
        }

    }

    private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
    { /*place your code here*/}


    private void cellEndEditTimer_Tick(object sender, EventArgs e)
    {
        dataGridView1.EndEdit();
        cellEndEditTimer.Stop();
    }
4
mustafabar

Versuchen Sie, das CellContentClick-Ereignis einzuhaken. DataGridViewCellEventArgs enthält einen ColumnIndex und einen RowIndex, damit Sie wissen können, ob tatsächlich eine ChecboxCell angeklickt wurde. Das Gute an diesem Ereignis ist, dass es nur ausgelöst wird, wenn das eigentliche Kontrollkästchen selbst angeklickt wurde. Wenn Sie auf den weißen Bereich der Zelle um das Kontrollkästchen klicken, wird es nicht ausgelöst. Auf diese Weise sind Sie ziemlich sicher, dass der Wert des Kontrollkästchens geändert wurde, als dieses Ereignis ausgelöst wurde. Sie können dann Invalidate () aufrufen, um Ihr Zeichenereignis auszulösen, sowie einen Aufruf von EndEdit (), um das Ende der Bearbeitung der Zeile auszulösen, falls Sie dies benötigen.

4
BFree

Das "EditingControlShowing" -Ereignis wird nicht bei einer Änderung der Checkbox-Werte ausgelöst. Der Anzeigestil der Kontrollkästchenzelle wird nicht geändert.

Die Problemumgehung, die ich verwendet habe, ist wie folgt. (Ich habe das CellContentClick-Ereignis verwendet.)

    private void gGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (string.Compare(gGridView1.CurrentCell.OwningColumn.Name, "CheckBoxColumn") == 0)
        {
            bool checkBoxStatus = Convert.ToBoolean(gGridView1.CurrentCell.EditedFormattedValue);
            //checkBoxStatus gives you whether checkbox cell value of selected row for the
            //"CheckBoxColumn" column value is checked or not. 
            if(checkBoxStatus)
            {
                //write your code
            }
            else
            {
               //write your code
            }
        }
    }

Das obige hat für mich gearbeitet. Bitte lassen Sie mich wissen, wenn Sie weitere Hilfe benötigen.

1
Yamanappa

cellEndEditTimer.Start ();

diese Zeile bewirkt, dass das Datenfenster die Liste der markierten Kästchen aktualisiert

Vielen Dank.

1
Leandro

Ich habe eine einfache Lösung gefunden.

Ändern Sie einfach den Zellenfokus, nachdem Sie auf die Zelle geklickt haben.

private void DGV_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.ColumnIndex == "Here checkbox column id or name") {
        DGV.Item(e.ColumnIndex, e.RowIndex + 1).Selected = true;
        //Here your code

    }
}

Vergessen Sie nicht zu überprüfen, ob die Spalte Ihres (ckeckbox + 1) -Index vorhanden ist.

1

Verwenden Sie diesen Code, wenn Sie das Ereignis checkedChanged in der DataGrid-Ansicht verwenden möchten:

private void grdBill_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
    grdBill.CurrentCell =  grdBill.Rows[grdBill.CurrentRow.Index].Cells["gBillNumber"];
}

private void grdBill_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    calcBill();
}

private void calcBill()
{
    listBox1.Items.Clear();
    for (int i = 0; i < grdBill.Rows.Count - 1; i++)
    {
        if (Convert.ToBoolean(grdBill.Rows[i].Cells["gCheck"].Value) == true)
        {
            listBox1.Items.Add(grdBill.Rows[i].Cells["gBillNumber"].Value.ToString());
        }
    }
}

Hier grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox in Grid (zweite Spalte).

Wenn also das checkcheckte Ereignis für jeden Klick ausgelöst werden soll, wird zuerst CellContentClick ausgelöst, wenn der Benutzer auf das Textfeld klickt. Dann wird die aktuelle Zelle in die nächste Spalte verschoben Geben Sie an, ob das Kontrollkästchen aktiviert ist, und fügen Sie die "gBillNumber" in das Listenfeld ein (in der Funktion calcBill).

0
Jegan

Ich fand eine Kombination der ersten beiden Antworten, die mir das gab, was ich brauchte. Ich habe das CurrentCellDirtyStateChanged-Ereignis verwendet und den EditedFormattedValue untersucht.

private void dgv_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
   DataGridView dgv = (DataGridView)sender;
   DataGridViewCell cell = dgv.CurrentCell;
   if (cell.RowIndex >= 0 && cell.ColumnIndex == 3) // My checkbox column
     {
        // If checkbox checked, copy value from col 1 to col 2
        if (dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue != null && dgv.Rows[cell.RowIndex].Cells[cell.ColumnIndex].EditedFormattedValue.Equals(true))
        {
           dgv.Rows[cell.RowIndex].Cells[1].Value = dgv.Rows[cell.RowIndex].Cells[2].Value;
        }
     }
}
0
Mike Pollitt

Mit einem ungebundenen Steuerelement arbeiten (dh ich verwalte den Inhalt programmgesteuert), ohne das EndEdit () wurde CurrentCellDirtyStateChanged nur einmal und dann nie wieder aufgerufen. aber ich fand heraus, dass mit der EndEdit () CurrentCellDirtyStateChanged zweimal aufgerufen wurde (die zweite wurde wahrscheinlich durch die EndEdit () verursacht, aber ich habe nicht nachgeprüft).

    bool myGridView_DoCheck = false;
    private void myGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        if (!myGridView_DoCheck)
        {
            myGridView_DoCheck = true;
            myGridView.EndEdit();
            // do something here
        }
        else
            myGridView_DoCheck = false;
    }

Jede der CellClick- und CellMouseClick-Antworten ist falsch, da Sie den Wert der Zelle mit der Tastatur ändern können und das Ereignis nicht ausgelöst wird. Außerdem wird CurrentCellDirtyStateChanged nur einmal ausgelöst, dh wenn Sie dasselbe Kästchen mehrmals aktivieren bzw. deaktivieren, wird nur ein Ereignis angezeigt. Wenn Sie einige der obigen Antworten kombinieren, erhalten Sie folgende einfache Lösung:

private void dgvList_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgvList.CurrentCell is DataGridViewCheckBoxCell)
        dgvList.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

private void dgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // Now this will fire immediately when a check box cell is changed,
    // regardless of whether the user uses the mouse, keyboard, or touchscreen.
    //
    // Value property is up to date, you DO NOT need EditedFormattedValue here.
}
0
Eric Lindsey