簡體   English   中英

DataGridView CheckBox單元格/列事件

[英]DataGridView CheckBox Cell/Column Event

如何在DataGridView的CheckBoxColumn中訂閱CheckBox的事件處理程序,類似於常規CheckBox的CheckChanged或Click事件處理程序? 我有一個或多個列,在我的應用程序中的多個數據網格中,我想這樣做。

我看過CellContentClick和CellClick,但它們似乎完全不優雅,因為它們會觸發數據網格中的每次點擊,而不僅僅是感興趣的Cell或CheckBox。

下面的解決方案來自於MSDN文檔以及在這里和CodeProject上的一些切向線程中的一點運氣。

我們的想法是創建一個派生自DataGridViewCheckBoxCell的類,該類包含一個與ContentClick一起觸發的處理程序。 對於一個DataGridView來說,這似乎有很多開銷,但我的應用程序有許多DataGridViews,因此這段代碼是可重用的,從而節省了時間。

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

由於我希望能夠從列類引用此單元類,因此我還實現了一個從DataGridViewCheckBoxColumn派生的類:

/// <summary>
/// DataGridView column class for a check box column with cells that have an OnContentClick handler.
/// </summary>
public class DataGridViewEventCheckBoxColumn : DataGridViewCheckBoxColumn
{
    /// <summary>
    /// Empty constructor.  Pass through to base constructor
    /// </summary>
    public DataGridViewEventCheckBoxColumn()
        : base()
    { }

    /// <summary>
    /// Pass through to base constructor with threeState parameter
    /// </summary>
    /// <param name="threeState">True for three state check boxes, True, False, Indeterminate.</param>
    public DataGridViewEventCheckBoxColumn(bool threeState)
        : base(threeState)
    { }

    /// <summary>
    /// Constructor for setting the OnContentClick event handler for the cell template.
    /// Note that the handler will be called for all clicks, even if the DataGridView is ReadOnly.
    /// For the "new" state of the checkbox, use the EditedFormattedValue property of the cell.
    /// </summary>
    /// <param name="handler">Event handler for OnContentClick.</param>
    /// <param name="threeState">True for three state check boxes, True, False, Indeterminate.</param>
    public DataGridViewEventCheckBoxColumn(EventHandler<DataGridViewCellEventArgs> handler, bool threeState)
        : base(threeState)
    {
        CellTemplate = new DataGridViewEventCheckBoxCell(handler, threeState);
    }
}

修剪掉多余的代碼,我正在使用它:

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

這是一個示例事件處理程序。 數據網格中另一列的狀態將根據此列的值進行更新,並有條件地更新WasReleased屬性中的某些狀態信息。 DataGridView的DataSource是Specimen對象的集合,因此每一行的DataBoundItem都是一個Specimen。 Specimen類是特定於應用程序的,但它具有此列顯示的OnHold屬性; IsReleased,由另一列顯示; 並被釋放。

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

好的樣式可能會將事件處理程序中的一些代碼推送到Specimen類中的方法中。

您可以使用

e.Item.Cells [1]。文本

這里e是當前行和第二個單元格,記住單元格索引始終以0索引開始

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM