DataGridViewColumn 的HeaderCell 可以随时替换。
即使已经设置了 DataGridView 的数据源:在这种情况下,您可能希望将当前 HeaderCell 的样式设置为新单元格,以防需要复制某些值(当列是自动-生成,可能没有太多要复制的,但是既然可以设置Style属性,那就设置吧)。
在示例中,我向自定义 HeaderCell 添加了一个 ReplaceHeaderCell() 方法,该方法接收当前标头的实例,复制一些属性,然后在替换相应的之前处理它列的HeaderCell 本身。
如果我们添加到HeaderCell 的按钮是标准按钮控件,则必须将此控件添加到DataGridView.Controls 集合中(这样它才会可见并放在前面)。
如果 Button 被绘制,覆盖Paint method,当然没有任何父项:)。
注意: Button 是在 OnDataGridViewChanged() 方法覆盖中添加的。每次 DataGridView 对象成为 HeaderCell 的所有者时都会调用此方法。当 Parent DataGridView 发生变化时,Button 会自动添加到其 Controls 集合中。
► 在这里,Paint 方法无论如何都会被覆盖:它用于计算 HeaderCell 文本填充,因此 Button 不会重叠并隐藏 Column 的文本(此过程需要根据 Button 的细节进行微调)。
要替换列的当前HeaderCell(例如Column[0]),只需创建自定义HeaderCell 的新实例并调用ReplaceHeaderCell() 方法,传递HeaderCell 的引用来替换:
var newButtonHeaderCell = new DGVButtonHeaderCell();
newButtonHeaderCell.ReplaceHeaderCell(dataGridView1.Columns[0].HeaderCell);
这就是它的工作原理:
using System.Drawing;
using System.Windows.Forms;
class DGVButtonHeaderCell : DataGridViewColumnHeaderCell
{
public readonly Button button;
private Padding m_ButtonPadding = Padding.Empty;
public DGVButtonHeaderCell(int buttonWidth = 40)
{
button = new Button() { BackColor = Color.Orange, Width = buttonWidth };
m_ButtonPadding = new Padding(button.Width + 2, 0, 0, 0);
button.Click += ButtonClick;
}
public void ReplaceHeaderCell(DataGridViewColumnHeaderCell previousHeader)
{
if (previousHeader == null) return;
SetStandardValues(previousHeader);
var dgv = previousHeader.DataGridView;
dgv.Columns[previousHeader.OwningColumn.Index].HeaderCell = this;
previousHeader.Dispose();
}
private void SetStandardValues(DataGridViewColumnHeaderCell previous)
{
if (previous == null) return;
this.Style = previous.Style;
button.Font = this.Style.Font ?? previous.DataGridView.ColumnHeadersDefaultCellStyle.Font;
// etc.
}
private void ButtonClick(object sender, EventArgs e)
{
OnClick(new DataGridViewCellEventArgs(ColumnIndex, RowIndex));
MessageBox.Show("You clicked me");
}
protected override void OnDataGridViewChanged()
{
if (this.DataGridView == null) return;
this.DataGridView.Controls.Add(button);
}
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)
{
cellStyle.Padding = Padding.Add(m_ButtonPadding, cellStyle.Padding);
base.Paint(g, clipBounds, bounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advBorderStyle, parts);
button.Location = new Point(bounds.Left, bounds.Top + 2);
button.Height = bounds.Height - 4;
}
protected override void Dispose(bool disposing)
{
if (disposing) {
button.MouseClick -= ButtonClick;
button.Dispose();
}
base.Dispose(disposing);
}
}