簡體   English   中英

在 DataGridView 中觸發復選框值更改事件

[英]Triggering a checkbox value changed event in DataGridView

我有一個帶有復選框列的網格視圖,我想在單元格的值被切換后立即觸發繪圖事件。 我嘗試了 ValueChaged 和 CellEndEdit 和 BeginEdit,並選擇了 CellSelect 作為選擇模式。 對於前2個事件,該事件是在編輯模式完成時觸發的,例如移出當前單元格,或來回移動。 這只是一種奇怪的行為。

一旦單元格值發生變化,是否有任何東西會觸發網格視圖上的事件?

我使用 CellContentClick 事件,它確保用戶單擊復選框。 即使用戶停留在同一個單元格中,它也會多次觸發。 一個問題是 Value 不會更新,並且總是返回“false”以表示未選中。 訣竅是使用單元格的 .EditedFormattedValue 屬性而不是 Value 屬性。 EditedFormattedValue 將使用復選標記進行跟蹤,並且當 CellContentClick 被觸發時,它是人們希望其中包含的值。

不需要計時器,不需要任何花哨的東西,只需使用 CellContentClick 事件並檢查 EditedFormattedValue 來判斷復選框正在進入/剛剛進入的狀態。 如果 EditedFormattedValue = true,則復選框被選中。

我的一位同事建議捕獲 CurrentCellDirtyStateChanged 事件。 請參閱http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcelldirtystatechanged.aspx

另一種方法是處理 CellContentClick 事件(它不會在單元格的 Value 屬性中為您提供當前值),調用 grid.CommitEdit(DataGridViewDataErrorContexts.Commit) 來更新值,這反過來將觸發 CellValueChanged,然后您可以獲得實際(即正確)DataGridViewCheckBoxColumn 值。

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
}

目標 .NET 框架:2.0

小更新......確保你使用EditedFormattedValue而不是value作為我嘗試的value但它永遠不會給出正確的狀態, EditedFormattedValue選中/未選中的大多數站點仍然使用value但在下面最新的c# 2010 express中使用的是一種訪問方式..

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

此外,少數人建議或使用的_CellValueChanged事件必須在某些情況下可用,但如果您正在查找單元格的每次檢查/取消檢查,請確保您使用_CellContentClick其他根據我的通知,我不是每次都看到_CellValueChanged被觸發..如果相同復選框被反復點擊它不會觸發_CellValueChanged但如果你交替點擊,例如你有兩個_CellValueChanged並在其他_CellValueChanged事件將被觸發之后點擊一個,但通常如果在每次選中/取消選中任何單元格時尋找要觸發的事件_CellValueChanged沒有被解雇。

我有同樣的問題,但想出了不同的解決方案:

如果您將列或整個網格設為“只讀”,則當用戶單擊復選框時,它不會更改值。

幸運的是, DataGridView.CellClick事件仍然被觸發。 就我而言,我在cellClick事件中執行以下cellClick

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

但是,如果您有多個復選框列,則可以檢查列名。

然后我自己完成數據集的所有修改/保存。

嘗試掛接到 CellContentClick 事件。 DataGridViewCellEventArgs 將有一個 ColumnIndex 和一個 RowIndex,因此您可以知道是否真的單擊了 CheckboxCell。 這個事件的好處是它只有在實際的復選框被點擊時才會觸發。 如果您單擊復選框周圍單元格的白色區域,它將不會觸發。 這樣,您幾乎可以保證在此事件觸發時復選框值已更改。 然后,您可以調用 Invalidate() 來觸發繪圖事件,如果需要,還可以調用 EndEdit() 來觸發行編輯的結束。

我終於以這種方式實現了

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

“EditingControlShowing”事件不會在復選框值更改時觸發。 因為復選框單元格的顯示樣式不會改變。

我使用的解決方法如下。 (我使用過 CellContentClick 事件)

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

以上對我有用。 如果需要更多幫助,請告訴我。

我找到了一個簡單的解決方案。

單擊單元格后只需更改單元格焦點。

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

    }
}

不要忘記檢查您的 (ckeckbox + 1) 索引的列是否存在。

CellClickCellMouseClick答案中的每一個都是錯誤的,因為您可以使用鍵盤更改單元格的值並且不會觸發事件。 此外, CurrentCellDirtyStateChanged只觸發一次,這意味着如果您多次選中/取消選中同一個框,您將只會收到一個事件。 結合上面的幾個答案給出了以下簡單的解決方案:

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

cellEndEditTimer.Start();

此行使 datagridview 更新復選框列表

謝謝你。

使用未綁定的控件(即我以編程方式管理內容),如果沒有 EndEdit(),它只調用 CurrentCellDirtyStateChanged 一次,然后再也不調用; 但是我發現使用 EndEdit() CurrentCellDirtyStateChanged 被調用了兩次(第二次可能是由 EndEdit() 引起的,但我沒有檢查),所以我做了以下操作,這對我來說效果最好:

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

使用.EditedFormattedValue屬性解決了這個問題

要在每次單擊單元格中的復選框切換值時收到通知,您可以使用CellContentClick事件並訪問初始單元格值.EditedFormattedValue

當事件被觸發時, .EditedFormattedValue尚未直觀地應用於復選框,也尚未提交給 .Value 屬性。

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
   var checkbox = dataGridView1.CurrentCell as DataGridViewCheckBoxCell;

   bool isChecked = (bool)checkbox.EditedFormattedValue;

}

事件在每次點擊時觸發, .EditedFormattedValue切換

我發現前兩個答案的組合給了我我需要的東西。 我使用了 CurrentCellDirtyStateChanged 事件並檢查了 EditedFormattedValue。

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

當您想在 DataGrid 視圖中使用checkedChanged事件時,請使用以下代碼:

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

這里, grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox Grid 中的grdBill = DataGridView1, gCheck = CheckBox in GridView(First Column), gBillNumber = TextBox (第二列)。

因此,當我們想為每次點擊觸發 checkchanged 事件時,首先執行 CellContentClick 當用戶單擊文本框時它會觸發,然后它將當前單元格移動到下一列,因此 CellEndEdit 列會觸發,它會檢查是否選中復選框並在列表框中添加“gBillNumber”(在函數 calcBill 中)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM