如何用自定义标题替换 DataGridView 的 HeaderCells?

Al2*_*110 4 .net c# datagridview winforms

当DataGridView 的 已经设置为DataGridViewColumnHeaderCell对象并且还保留之前的 HeaderCell 的文本(设置为 DataTable 相应列的名称)时,何时用自定义替换a HeaderCell(此处:)?CustomDataGridViewColumnHeaderCellDataSourceDataTable

我有一个自定义标头类DataGridView:

public class CustomDataGridViewColumnHeaderCell : DataGridViewColumnHeaderCell
{
    // adds a button to the header
}
Run Code Online (Sandbox Code Playgroud)

ADataTable被设置为DataSource,列将自动创建。如何用自定义标题单元格(上述实例)替换默认标题单元格?

更多详情

在此输入图像描述

要解决的问题是,DataGridView需要在其标题单元格中嵌入可点击的按钮,即上面屏幕截图中箭头所指的位置。为此,有一类CustomDataGridViewColumnHeaderCell. 为了显示 中的数据DataGridView,DataTable将 a 指定为其数据源。例如:

myDataGridView.DataSource = myDataTable;
Run Code Online (Sandbox Code Playgroud)

执行此操作后,DataGridView将具有与 中的列相对应的列DataTable。我从默认标题类派生了一个类,以便按钮出现在列标题内。

Jim*_*imi 7

DataGridViewColumn的 HeaderCell可以随时替换。

\n

即使 DataGridView 的 DataSource 已经设置:在这种情况下,您可能需要设置当前的 StyleHeaderCell为新单元格,以防需要复制某些值(当自动生成列时,会出现\'可能没有太多需要复制的内容,但由于可以设置 Style 属性,所以让我们设置它)。

\n

ReplaceHeaderCell()在示例中,我向 custom添加一个方法,该方法接收当前标头的实例,复制一些属性,然后在用其自身HeaderCell替换相应的 Column 之前对其进行处理。HeaderCell

\n

如果我们要添加的按钮是HeaderCell标准按钮控件,则必须将该控件添加到DataGridView.Controls集合中(这样它将可见并置于前面)。
\n如果 Button 被绘制,重写Paint 方法,当然没有任何父级:)。

\n

注意: Button 是在OnDataGridViewChanged()方法重写中添加的。每次 DataGridView 对象成为 HeaderCell 的所有者时都会调用此方法。当父 DataGridView 更改时,Button 会自动添加到其 Controls 集合中。

\n

\xe2\x96\xba 在这里,Paint 方法无论如何都会被重写:它用于计算 HeaderCell 文本填充,因此按钮不会重叠并隐藏 Column 的文本(此过程需要很好) -根据按钮的具体情况进行调整)。

\n

要替换当前HeaderCell的列(例如,Column[0]),只需创建自定义的新实例HeaderCell并调用该方法,传递要替换ReplaceHeaderCell()的引用:HeaderCell

\n
var newButtonHeaderCell = new DGVButtonHeaderCell();\nnewButtonHeaderCell.ReplaceHeaderCell(dataGridView1.Columns[0].HeaderCell);\n
Run Code Online (Sandbox Code Playgroud)\n

它是这样工作的:

\n

DataGridView 自定义 HeaderCell

\n
using System.Drawing;\nusing System.Windows.Forms;\n\nclass DGVButtonHeaderCell : DataGridViewColumnHeaderCell\n{\n    public readonly Button button;\n    private Padding m_ButtonPadding = Padding.Empty;\n\n    public DGVButtonHeaderCell(int buttonWidth = 40)\n    {\n        button = new Button() { BackColor = Color.Orange, Width = buttonWidth };\n        m_ButtonPadding = new Padding(button.Width + 2, 0, 0, 0);\n        button.Click += ButtonClick;\n    }\n\n    public void ReplaceHeaderCell(DataGridViewColumnHeaderCell previousHeader)\n    {\n        if (previousHeader == null) return;\n        SetStandardValues(previousHeader);\n        var dgv = previousHeader.DataGridView;\n        dgv.Columns[previousHeader.OwningColumn.Index].HeaderCell = this;\n        previousHeader.Dispose();\n    }\n\n    private void SetStandardValues(DataGridViewColumnHeaderCell previous)\n    {\n        if (previous == null) return;\n        Style = previous.Style;\n        button.Font = Style.Font ?? previous.DataGridView.ColumnHeadersDefaultCellStyle.Font;\n        // etc.\n    }\n\n    private void ButtonClick(object sender, EventArgs e)\n    {\n        OnClick(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));\n        MessageBox.Show("You clicked me");\n    }\n\n    protected override void OnDataGridViewChanged()\n    {\n        if (DataGridView == null) return;\n        DataGridView.Controls.Add(button);\n    }\n\n    protected override void Paint(Graphics g, Rectangle clipBounds, Rectangle bounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advBorderStyle, DataGridViewPaintParts parts)\n    {\n        cellStyle.Padding = Padding.Add(m_ButtonPadding, cellStyle.Padding);\n        base.Paint(g, clipBounds, bounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advBorderStyle, parts);\n        button.Location = new Point(bounds.Left, bounds.Top + 2);\n        button.Height = bounds.Height - 4;\n    }\n\n    protected override void Dispose(bool disposing)\n    {\n        if (disposing) {\n            button.MouseClick -= ButtonClick;\n            button.Dispose();\n        }\n        base.Dispose(disposing);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n