本文介绍了DataGridView CheckBox事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一系列复选框,使用相同的标签在水平和垂直方向上创建一个 DataGridView 。任何标签相同,复选框将不起作用,我只希望每个组合的两个检查之一是有效的。以下屏幕截图显示了我的内容:



在下半部分检查的任何东西,我希望UN在上面检查。所以如果[quux,spam](或[7,8]为零为坐标)被检查,我想[垃圾邮件,quux]([8,7])未检查。到目前为止,我已经有以下几点:

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

//为每个条目添加列,并为每个条目添加一行,并将对角线标记为只读
(int i = 0; i {
dgvSysGrid.Columns.Add(new DataGridViewCheckBoxColumn(false));
dgvSysGrid.Columns [i] .HeaderText = allsysNames [i];
dgvSysGrid.Rows.Add();
dgvSysGrid.Rows [i] .HeaderCell.Value = allsysNames [i];
//将所有对角线标记为无法更改
DataGridViewCell curDiagonal = dgvSysGrid [i,i];
curDiagonal.ReadOnly = true;
curDiagonal.Style.BackColor = Color.Black;
curDiagonal.Style.ForeColor = Color.Black;
}

//挂接事件处理程序,以便我们可以根据需要更改对应复选框
//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);

//将对角线复选框更改为相反的状态
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>
///将相应的复选框更改为当前一个的相反状态
///< / summary>
///< param name =sender>< / param>
///< param name =e>< / param>
void dgvSysGrid_CurrentCellDirtyStateChanged(object sender,EventArgs e)
{
Point cur = dgvSysGrid.CurrentCellAddress;

//将对角线复选框更改为相反的状态
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作为一个空值(建议当前的单元格地址是错误的,但我没有尝试得到该值),这意味着该路径根本不起作用。



基本上,如何使用正确的布尔值获取正确的地址,以便我的翻转算法可以正常工作?

解决方案

最终,它是 CurrentCellDirtyStateChanged 事件,但您需要以正确的方式执行。正确的方法是' s / p>

上面的片段以及我最终所做的是如下:

  //挂接事件处理程序,以便我们可以根据需要更改对应复选框
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);

//将对角线复选框更改为相反的状态
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 事件,那么只有在您离开单元格之后才会触发。我不知道为什么(考虑到它是一个复选框,不是立即完成),但是这是怎么回事。并且上面的代码工作,因为复选框的更改在右键单击它。所以它的工作。


I'm making a DataGridView with a series of Checkboxes in it with the same labels horizontally and vertically. Any labels that are the same, the checkboxes will be inactive, and I only want one of the two "checks" for each combination to be valid. The following screenshot shows what I have:DataGridView http://i46.tinypic.com/2e4m3pz.png

Anything that's checked on the lower half, I want UN-checked on the upper. So if [quux, spam] (or [7, 8] for zero-based co-ordinates) is checked, I want [spam, quux] ([8, 7]) un-checked. What I have so far is the following:

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

The problem comes is that the cell value changed always seems to be "one behind" where you actually click if I use the CellValueChanged event, and I'm not sure how to get the current cell if I'm in the "dirty" state as curCell comes in as a null (suggesting the current cell address is wrong somehow, but I didn't try and get that value out) meaning that path isn't working at all.

Basically, how do I get the "right" address with the right boolean value so that my flipping algorithm will work?

解决方案

Ultimately, it was the CurrentCellDirtyStateChanged event that does it, but you need to do it in the right way. And the right way is MSDN's, though it doesn't make sense at first glance.

A fragment from above, and what I ultimately did is below:

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

Basically, all that's happening is the CurrentCellDirtyStateChanged event triggers the CellValueChanged event, and that's it. If you just attach the CellValueChanged event, then it only triggers AFTER you have left the cell. I don't know why exactly (considering it's a checkbox, isn't it "done" immediately?), but that's what happens. And the code as above works, in that the check box changes go in RIGHT away when clicking it. So it works.

这篇关于DataGridView CheckBox事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 15:24