首页 > 解决方案 > 在 CellValueChanged 期间 winform datagridview 更新值

问题描述

我正在构建这样的应用程序:

在此处输入图像描述

在表格的每一行中:

我正在使用 Winforms 中的 DataGridView 实现上述应用程序。以下是我的代码:

public partial class Form1 : Form
    {
        DataTable dataTable;

        public Form1()
        {
            InitializeComponent();

            dataTable = new DataTable();
            dataTable.Columns.Add("Item");
            dataTable.Columns.Add("All option", typeof(CheckState));
            dataTable.Columns.Add("Option 1", typeof(bool));
            dataTable.Columns.Add("Option 2", typeof(bool));
            dataTable.Rows.Add("Item 1", CheckState.Unchecked, false, false);
            dataTable.Rows.Add("Item 2", CheckState.Unchecked, false, false);
            dataGrid.DataSource = dataTable;

        }

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

        bool isUnderUpdateAll = false;

        private void dataGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if ((dataGrid.CurrentCell is DataGridViewCheckBoxCell) == false) return;

            // This is column "All option"
            if (e.ColumnIndex == 1)
            {
                // Avoid stackoverflow exception
                if (isUnderUpdateAll) return;

                CheckState allOption = (CheckState)dataGrid["All option", e.RowIndex].Value;
                
                // Don't allow user select 'indeterminate' value
                if (allOption == CheckState.Indeterminate)
                {
                    allOption = CheckState.Unchecked;

                    // These code didn't work
                    dataTable.Rows[e.RowIndex]["All option"] = CheckState.Unchecked;
                    dataGrid["All option", e.RowIndex].Value = CheckState.Unchecked;
                    dataGrid.UpdateCellValue(e.ColumnIndex, e.RowIndex);
                    dataGrid.NotifyCurrentCellDirty(true);
                    dataGrid.Refresh();
                    dataGrid.Update();

                }

                dataGrid["Option 1", e.RowIndex].Value = allOption;
                dataGrid["Option 2", e.RowIndex].Value = allOption;
            }

            // This is column "Option 1" or "Option 2"
            else
            {
                bool option1 = (bool)dataGrid["Option 1", e.RowIndex].Value;
                bool option2 = (bool)dataGrid["Option 2", e.RowIndex].Value;

                isUnderUpdateAll = true;
                dataGrid["All option", e.RowIndex].Value = (option1 && option2) ? CheckState.Checked 
                    : (!option1 && !option2 ? CheckState.Unchecked : CheckState.Indeterminate );
                isUnderUpdateAll = false;
            }
        }
    }

该代码似乎有效,但有 1 个不完整的点:用户仍然能够在列中切换到Indeterminate状态All option。在我的代码中,我已经添加了许多内容,例如:

// Don't allow user select 'indeterminate' value
if (allOption == CheckState.Indeterminate)
{
    allOption = CheckState.Unchecked;

    // These code didn't work
    dataTable.Rows[e.RowIndex]["All option"] = CheckState.Unchecked;
    dataGrid["All option", e.RowIndex].Value = CheckState.Unchecked;
    dataGrid.UpdateCellValue(e.ColumnIndex, e.RowIndex);
    dataGrid.NotifyCurrentCellDirty(true);
    dataGrid.Refresh();
    dataGrid.Update();

}

但是这些代码不起作用。当单击复选框时,状态仍然在Checked -> indeterminate -> Unchecked -> Checked -> ...All option之间切换。 那么,有人可以帮助建议如何从上面删除不确定状态吗? 我希望它是:选中->未选中->选中->未选中...

标签: c#winformsdatagridview

解决方案


尝试将 设置CheckBox.ThreeState Property为 false。

((DataGridViewCheckBoxCell)(dataGrid.CurrentCell)).ThreeState = false;

推荐阅读