c# - DataGridView 复选框事件

标签 c# .net datagridview checkbox

我正在制作一个 DataGridView,其中包含一系列水平和垂直方向具有相同标签的复选框。任何相同的标签,复选框都将处于非事件状态,我只希望每个组合的两个“检查”之一有效。以下屏幕截图显示了我所拥有的: DataGridView

任何在下半部分经过检查的东西,我都希望在上半部分进行 UN-checked。因此,如果选中 [quux, spam](或 [7, 8] 对于基于零的坐标),我希望取消选中 [spam, quux] ([8, 7])。到目前为止,我有以下内容:

    dgvSysGrid.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
    dgvSysGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
    string[] allsysNames = { "heya", "there", "lots", "of", "names", "foo", "bar", "quux", "spam", "eggs", "bacon" };

    // Add a column for each entry, and a row for each entry, and mark the "diagonals" as readonly
    for (int i = 0; i < allsysNames.Length; i++)
    {
        dgvSysGrid.Columns.Add(new DataGridViewCheckBoxColumn(false));
        dgvSysGrid.Columns[i].HeaderText = allsysNames[i];
        dgvSysGrid.Rows.Add();
        dgvSysGrid.Rows[i].HeaderCell.Value = allsysNames[i];
        // Mark all of the "diagonals" as unable to change
        DataGridViewCell curDiagonal = dgvSysGrid[i, i];
        curDiagonal.ReadOnly = true;
        curDiagonal.Style.BackColor = Color.Black;
        curDiagonal.Style.ForeColor = Color.Black;
    }

    // Hook up the event handler so that we can change the "corresponding" checkboxes as needed
    //dgvSysGrid.CurrentCellDirtyStateChanged += new EventHandler(dgvSysGrid_CurrentCellDirtyStateChanged);
    dgvSysGrid.CellValueChanged += new DataGridViewCellEventHandler(dgvSysGrid_CellValueChanged);

}

void dgvSysGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    Point cur = new Point(e.ColumnIndex, e.RowIndex);

    // Change the diagonal checkbox to the opposite state
    DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.X, cur.Y];
    DataGridViewCheckBoxCell diagCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.Y, cur.X];
    if ((bool)(curCell.Value) == true)
    {
        diagCell.Value = false;
    }
    else
    {
        diagCell.Value = true;
    }
}

/// <summary>
/// Change the corresponding checkbox to the opposite state of the current one
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void dgvSysGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    Point cur = dgvSysGrid.CurrentCellAddress;

    // Change the diagonal checkbox to the opposite state
    DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.X, cur.Y];
    DataGridViewCheckBoxCell diagCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.Y, cur.X];
    if ((bool)(curCell.Value) == true)
    {
        diagCell.Value = false;
    }
    else
    {
        diagCell.Value = true;
    }
} 

问题是,如果我使用 CellValueChanged 事件,更改的单元格值似乎总是“落后于”您实际点击的位置,而且我不确定如何获取当前单元格如果我处于“脏”状态,因为 curCell 以 null 形式出现(暗示当前单元地址不知何故是错误的,但我没有尝试获取该值)意味着该路径根本不起作用。

基本上,我如何获得具有正确 bool 值的“正确”地址,以便我的翻转算法起作用?

最佳答案

最终,它是 CurrentCellDirtyStateChanged 事件完成的,但您需要以正确的方式完成。正确的方法是MSDN的,虽然乍一看没有意义。

上面的片段,下面是我最终做的:

    // Hook up the event handler so that we can change the "corresponding" checkboxes as needed
    dgvSysGrid.CurrentCellDirtyStateChanged += new EventHandler(dgvSysGrid_CurrentCellDirtyStateChanged);
    dgvSysGrid.CellValueChanged += new DataGridViewCellEventHandler(dgvSysGrid_CellValueChanged);

}

void dgvSysGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    Point cur = new Point(e.ColumnIndex, e.RowIndex);

    // Change the diagonal checkbox to the opposite state
    DataGridViewCheckBoxCell curCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.X, cur.Y];
    DataGridViewCheckBoxCell diagCell = (DataGridViewCheckBoxCell)dgvSysGrid[cur.Y, cur.X];
    if ((bool)(curCell.Value) == true)
    {
        diagCell.Value = false;
    }
    else
    {
        diagCell.Value = true;
    }
}

void dgvSysGrid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgvSysGrid.IsCurrentCellDirty)
    {
        dgvSysGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}

基本上,所有发生的事情都是 CurrentCellDirtyStateChanged 事件触发了 CellValueChanged 事件,仅此而已。如果您只是附加 CellValueChanged 事件,那么它只会在您离开单元格后触发。我不知道为什么(考虑到它是一个复选框,它不是立即“完成”吗?),但这就是发生的事情。上面的代码有效,因为当单击它时,复选框会立即更改。所以它有效。

关于c# - DataGridView 复选框事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2885391/

相关文章:

c# - JWT header 算法 : is "hs256" the same as "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256"

c# - MySql查询不显示结果

c# - 以编程方式更改datagridview中的颜色单元格

c# - 在 XNA 中使用 GIF

c# - 从 listView 中只选择一个项目

c# - 使用包含变量名称的字符串访问变量

c# - 单击 DataGridView 中的行标题的事件

c# - 在 Panel 而不是 DataGridView 上滚动

c# - 您将如何对数据注释进行单元测试?

c# - 在 ModelState.Errors 中使用 [JsonProperty ("name")]