C# DataGridView复选框单元格/列事件
如何订阅DataGridView的CheckBox列中复选框的事件处理程序(类似于常规复选框的CheckChanged或Click事件处理程序)?我有一个或多个列,在我的应用程序中的多个数据网格中,我想这样做 我已经看过了CellContentClick和CellClick,但它们看起来完全不雅观,因为它们在数据网格中的每一次点击都会触发,而不仅仅是对感兴趣的单元格或复选框 e、 Item.Cells[1]。文本 这里e是当前行,第二个单元格记住单元格索引始终以0开始,您可以使用 e、 Item.Cells[1]。文本C# DataGridView复选框单元格/列事件,c#,datagridview,checkbox,event-handling,click,C#,Datagridview,Checkbox,Event Handling,Click,如何订阅DataGridView的CheckBox列中复选框的事件处理程序(类似于常规复选框的CheckChanged或Click事件处理程序)?我有一个或多个列,在我的应用程序中的多个数据网格中,我想这样做 我已经看过了CellContentClick和CellClick,但它们看起来完全不雅观,因为它们在数据网格中的每一次点击都会触发,而不仅仅是对感兴趣的单元格或复选框 e、 Item.Cells[1]。文本 这里e是当前行,第二个单元格记住单元格索引始终以0开始,您可以使用 e、 Item
这里e是当前行和第二个单元格记住单元格索引总是以0索引开始。下面的解决方案来自于对MSDN文档的大量阅读,以及在这里和CodeProject上的一些切线线程中的一点运气 其思想是创建一个派生自DataGridViewCheckBoxCell的类,该类包括一个随ContentClick一起触发的处理程序。对于一个DataGridView来说,这似乎是很大的开销,但我的应用程序有很多DataGridView,因此此代码是可重用的,从而节省了时间
/// <summary>
/// DataGridView cell class for check box cells with a OnContentClick event handler.
/// </summary>
public class DataGridViewEventCheckBoxCell : DataGridViewCheckBoxCell
{
/// <summary>
/// Event handler for OnContentClick event.
/// </summary>
protected EventHandler<DataGridViewCellEventArgs> ContentClickEventHandler { get; set; }
/// <summary>
/// Empty constructor. Required. Used by Clone mechanism
/// </summary>
public DataGridViewEventCheckBoxCell()
: base()
{ }
/// <summary>
/// Pass through constructor for threeState parameter.
/// </summary>
/// <param name="threeState">True for three state check boxes, True, False, Indeterminate.</param>
public DataGridViewEventCheckBoxCell(bool threeState)
: base(threeState)
{ }
/// <summary>
/// Constructor to set the OnContentClick event handler.
/// Signature for handler should be (object sender, DataGridViewCellEventArgs e)
/// The sender will be the DataGridViewCell that is clicked.
/// </summary>
/// <param name="handler">Handler for OnContentClick event</param>
/// <param name="threeState">True for three state check boxes, True, False, Indeterminate.</param>
public DataGridViewEventCheckBoxCell(EventHandler<DataGridViewCellEventArgs> handler, bool threeState)
: base(threeState)
{
ContentClickEventHandler = handler;
}
/// <summary>
/// Clone method override. Required so CheckEventHandler property is cloned.
/// Individual DataGridViewCells are cloned from the DataGridViewColumn.CellTemplate
/// </summary>
/// <returns></returns>
public override object Clone()
{
DataGridViewEventCheckBoxCell clone = (DataGridViewEventCheckBoxCell)base.Clone();
clone.ContentClickEventHandler = ContentClickEventHandler;
return clone;
}
/// <summary>
/// Override implementing OnContentClick event propagation
/// </summary>
/// <param name="e">Event arg object, which contains row and column indexes.</param>
protected override void OnContentClick(DataGridViewCellEventArgs e)
{
base.OnContentClick(e);
if (ContentClickEventHandler != null)
ContentClickEventHandler(this, e);
}
/// <summary>
/// Override implementing OnContentDoubleClick event propagation
/// Required so fast clicks are handled properly.
/// </summary>
/// <param name="e">Event arg object, which contains row and column indexes.</param>
protected override void OnContentDoubleClick(DataGridViewCellEventArgs e)
{
base.OnContentDoubleClick(e);
if (ContentClickEventHandler != null)
ContentClickEventHandler(this, e);
}
}
好的样式可能会将事件处理程序中的一些代码下推到样本类中的一个方法中。下面的解决方案来自于对MSDN文档的浏览,以及在这里和CodeProject上的一些相关线程中的一点运气 其思想是创建一个派生自DataGridViewCheckBoxCell的类,该类包括一个随ContentClick一起触发的处理程序。对于一个DataGridView来说,这似乎是很大的开销,但我的应用程序有很多DataGridView,因此此代码是可重用的,从而节省了时间
/// <summary>
/// DataGridView cell class for check box cells with a OnContentClick event handler.
/// </summary>
public class DataGridViewEventCheckBoxCell : DataGridViewCheckBoxCell
{
/// <summary>
/// Event handler for OnContentClick event.
/// </summary>
protected EventHandler<DataGridViewCellEventArgs> ContentClickEventHandler { get; set; }
/// <summary>
/// Empty constructor. Required. Used by Clone mechanism
/// </summary>
public DataGridViewEventCheckBoxCell()
: base()
{ }
/// <summary>
/// Pass through constructor for threeState parameter.
/// </summary>
/// <param name="threeState">True for three state check boxes, True, False, Indeterminate.</param>
public DataGridViewEventCheckBoxCell(bool threeState)
: base(threeState)
{ }
/// <summary>
/// Constructor to set the OnContentClick event handler.
/// Signature for handler should be (object sender, DataGridViewCellEventArgs e)
/// The sender will be the DataGridViewCell that is clicked.
/// </summary>
/// <param name="handler">Handler for OnContentClick event</param>
/// <param name="threeState">True for three state check boxes, True, False, Indeterminate.</param>
public DataGridViewEventCheckBoxCell(EventHandler<DataGridViewCellEventArgs> handler, bool threeState)
: base(threeState)
{
ContentClickEventHandler = handler;
}
/// <summary>
/// Clone method override. Required so CheckEventHandler property is cloned.
/// Individual DataGridViewCells are cloned from the DataGridViewColumn.CellTemplate
/// </summary>
/// <returns></returns>
public override object Clone()
{
DataGridViewEventCheckBoxCell clone = (DataGridViewEventCheckBoxCell)base.Clone();
clone.ContentClickEventHandler = ContentClickEventHandler;
return clone;
}
/// <summary>
/// Override implementing OnContentClick event propagation
/// </summary>
/// <param name="e">Event arg object, which contains row and column indexes.</param>
protected override void OnContentClick(DataGridViewCellEventArgs e)
{
base.OnContentClick(e);
if (ContentClickEventHandler != null)
ContentClickEventHandler(this, e);
}
/// <summary>
/// Override implementing OnContentDoubleClick event propagation
/// Required so fast clicks are handled properly.
/// </summary>
/// <param name="e">Event arg object, which contains row and column indexes.</param>
protected override void OnContentDoubleClick(DataGridViewCellEventArgs e)
{
base.OnContentDoubleClick(e);
if (ContentClickEventHandler != null)
ContentClickEventHandler(this, e);
}
}
好的样式可能会将事件处理程序中的一些代码下推到样本类中的方法中。可能重复:,或者是的,可能重复,但我相信有一个有趣的解决方案。我是一个长期的读者,但一个新的海报。我只是想在这里有所贡献。对于一条可能会在嘈杂声中迷失方向的长线,发布另一个答案是否更好?作为一个想做同样事情的人,我还没有看到任何聪明的方法来做到这一点。此列类型不使用EditControl功能,并且DataGridViewCheckboxCell没有任何有趣的事件。我认为如果你在寻找其他信息,一个新问题是可以的,只要你说清楚。@gmlobdell你可以回答你自己的问题。它在SO中有效。我在等你的答复!:对下面答案的反馈?感谢投票。可能重复:,或者是的,可能重复,但我相信有一个有趣的解决方案。我是一个长期的读者,但一个新的海报。我只是想在这里有所贡献。对于一条可能会在嘈杂声中迷失方向的长线,发布另一个答案是否更好?作为一个想做同样事情的人,我还没有看到任何聪明的方法来做到这一点。此列类型不使用EditControl功能,并且DataGridViewCheckboxCell没有任何有趣的事件。我认为如果你在寻找其他信息,一个新问题是可以的,只要你说清楚。@gmlobdell你可以回答你自己的问题。它在SO中有效。我在等你的答复!:对下面答案的反馈?e通常是EventArgs类型的EventHandler参数或从EventArgs派生的类型。这有什么帮助?您将订阅什么事件,以及订阅什么对象/控件,以便使用对象发送方DataGridViewCellEventArgs调用事件处理程序。通常,发送方是行,或者可以从中获取行的其他对象。请编辑以提供更多详细信息。e通常是EventArgs类型的EventHandler参数或从EventArgs派生的类型。这有什么帮助?您将订阅什么事件,以及订阅什么对象/控件,以便使用对象发送方DataGridViewCellEventArgs调用事件处理程序。通常,发送方是行,或者可以从中获取行的其他对象。请编辑以提供更多详细信息。创意+1。然而,就我自己而言,我只有一个datagridview,这是为活动投入的大量时间/资源。Patrick Quirk的第二个链接似乎是更快的解决方案。尝试一下。创造力+1。然而,就我自己而言,我只有一个datagridview,这是为活动投入的大量时间/资源。Patrick Quirk的第二个链接似乎是更快的解决方案。试试看。
public void AddCheckBoxColumn(DataGridView grid, EventHandler<DataGridViewCellEventArgs> handler, bool threeState)
{
grid.Columns.Add(new DataGridViewEventCheckBoxColumn(handler, threeState));
}
public void AddCheckBoxColumn(DataGridView grid, EventHandler<DataGridViewCellEventArgs> handler, bool threeState)
{
DataGridViewCheckBoxColumn column = new DataGridViewCheckBoxColumn(threeState);
column.CellTemplate = new DataGridViewEventCheckBoxCell(handler, threeState);
grid.Columns.Add(column);
}
public static void OnHoldCheckClick(object sender, DataGridViewCellEventArgs e)
{
if (sender is DataGridViewEventCheckBoxCell)
{
DataGridViewEventCheckBoxCell cell = sender as DataGridViewEventCheckBoxCell;
if (!cell.ReadOnly)
{
// The rows in the DataGridView are bound to Specimen objects
Specimen specimen = (Specimen)cell.OwningRow.DataBoundItem;
// Modify the underlying data source
if ((bool)cell.EditedFormattedValue)
specimen.IsReleased = false;
else if (specimen.WasReleased)
specimen.IsReleased = true;
// Then invalidate the cell in the other column to force it to redraw
DataGridViewCell releasedCell = cell.OwningRow.Cells["IsReleased"];
cell.DataGridView.InvalidateCell(releasedCell);
}
}
}