【发布时间】:2021-03-21 12:25:39
【问题描述】:
我正在构建这样的应用程序:
在表格的每一行内:
-
用户可以选中或取消选中
Option 1和Option 2列中的值。
之后,All option列中复选框的值将更新为:
- “已选中”:如果Option 1和Option 2都已选中
- “未选中”:如果Option 1和Option 2都未选中
- “不确定”:其他情况 -
用户可以选中或取消选中
All option列中的值。
之后,Option 1和Option 2的值都将根据All option的当前值进行更新。
在这种情况下,用户无法将All option列的值更改为Indeterminate(只能在Checked 和Unchecked 之间切换)。
我正在使用 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 点不完整:用户仍然能够在 All option 列中切换到 Indeterminate 状态。在我的代码中,我已经添加了许多类似的内容:
// 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();
}
但是这些代码不起作用。当点击All option复选框时,状态仍然在Checked -> indeterminate -> Unchecked -> Checked之间切换> -> ...
那么,有人可以帮助建议如何从上面删除 indeterminate 状态吗?
我希望它是:Checked -> Unchecked -> Checked -> Unchecked ...
【问题讨论】:
标签: c# winforms datagridview