DataGridView的复选框事件 [英] DataGridView CheckBox events

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

问题描述

我在做一个 DataGridView的在它的一系列的复选框以水平和垂直方向相同的标签。是相同的任何标签,复选框将不起作用,我只希望两个检查,每个组合是有效的一个。下面的截图显示我有:



< p,该公司在下半部检查>什么,我想在上联合国检查。所以,如果[QUUX,垃圾邮件(或[7,8]对于零基础坐标)被选中,我希望[垃圾邮件,QUUX]([8,7])未检查。我至今如下:

  dgvSysGrid.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; 
dgvSysGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
的String [] allsysNames = {部屋,有,手,中,姓名,富,酒吧,QUUX,垃圾邮件,蛋 培根 };
$ B $B∥加上每个条目的一列,并为每个条目的行,并标记对角线作为只读
表示(INT I = 0; I&下; allsysNames.Length;我++)
{
dgvSysGrid.Columns.Add(新DataGridViewCheckBoxColumn(假));
dgvSysGrid.Columns [I] .HeaderText = allsysNames [I]
dgvSysGrid.Rows.Add();
dgvSysGrid.Rows [I] .HeaderCell.Value = allsysNames [I]
//马克所有的对角线为无法改变
的DataGridViewCell curDiagonal = dgvSysGrid [我,我]
curDiagonal.ReadOnly = TRUE;
curDiagonal.Style.BackColor = Color.Black;
curDiagonal.Style.ForeColor = Color.Black;
}

//挂钩事件处理程序,使我们可以改变对应的复选框根据需要
//dgvSysGrid.CurrentCellDirtyStateChanged + =新的EventHandler(dgvSysGrid_CurrentCellDirtyStateChanged);
dgvSysGrid.CellValueChanged + =新DataGridViewCellEventHandler(dgvSysGrid_CellValueChanged);

}

无效dgvSysGrid_CellValueChanged(对象发件人,DataGridViewCellEventArgs E)
{
点CUR =新的点(e.ColumnIndex,e.RowIndex);

//对角线复选框更改为相反的状态
DataGridViewCheckBoxCell curCell =(DataGridViewCheckBoxCell)dgvSysGrid [cur.X,cur.Y]
DataGridViewCheckBoxCell diagCell =(DataGridViewCheckBoxCell)dgvSysGrid [cur.Y,cur.X]
如果((布尔)(curCell.Value)==真)
{
diagCell.Value = FALSE;
}
,否则
{
diagCell.Value = TRUE;
}
}

///<总结>
///相应的复选框更改为当前
/// 1所述的相反状态; /总结>
///< PARAM NAME =发件人>< /参数>
///< PARAM NAME =E>< /参数>
无效dgvSysGrid_CurrentCellDirtyStateChanged(对象发件人,EventArgs五)
{
点CUR = dgvSysGrid.CurrentCellAddress;

//对角线复选框更改为相反的状态
DataGridViewCheckBoxCell curCell =(DataGridViewCheckBoxCell)dgvSysGrid [cur.X,cur.Y]
DataGridViewCheckBoxCell diagCell =(DataGridViewCheckBoxCell)dgvSysGrid [cur.Y,cur.X]
如果((布尔)(curCell.Value)==真)
{
diagCell.Value = FALSE;
}
,否则
{
diagCell.Value = TRUE;
}
}



这个问题来的是,单元格值改变似乎总是是一大截,您实际点击,如果我使用 CellValueChanged 事件,我不知道如何获取当前单元格,如果我在肮脏的很状态curCell进来为空(暗示当前单元格地址是有点不对,但我并没有尝试,并获得该值了),这意味着路径不工作的。



基本上,我如何才能用正确的布尔值正确的地址,以便我翻转算法是否行得通呢?


解决方案

归根结底,这是做它的 CurrentCellDirtyStateChanged 事件,但你需要做的是正确的方式。而正确的方法是 MSDN 的,虽然它不。'T意义乍一看



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

  //挂钩事件处理程序,使我们可以改变对应的复选框根据需要
dgvSysGrid.CurrentCellDirtyStateChanged + =新的EventHandler(dgvSysGrid_CurrentCellDirtyStateChanged);
dgvSysGrid.CellValueChanged + =新DataGridViewCellEventHandler(dgvSysGrid_CellValueChanged);

}

无效dgvSysGrid_CellValueChanged(对象发件人,DataGridViewCellEventArgs E)
{
点CUR =新的点(e.ColumnIndex,e.RowIndex);

//对角线复选框更改为相反的状态
DataGridViewCheckBoxCell curCell =(DataGridViewCheckBoxCell)dgvSysGrid [cur.X,cur.Y]
DataGridViewCheckBoxCell diagCell =(DataGridViewCheckBoxCell)dgvSysGrid [cur.Y,cur.X]
如果((布尔)(curCell.Value)==真)
{
diagCell.Value = FALSE;
}
,否则
{
diagCell.Value = TRUE;
}
}

无效dgvSysGrid_CurrentCellDirtyStateChanged(对象发件人,EventArgs五)
{
如果(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:

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的复选框事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆