使用自定义单元格绘制实际上很容易做到这一点。
你需要做的就是处理DataGridViewCellPainting事件:
dataGridView1.CellPainting += new DataGridViewCellPaintingEventHandler(dataGridView1_CellPainting);
在处理程序中做这样的事情:
void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == -1)
{
e.Paint(e.CellBounds, DataGridViewPaintParts.All &~DataGridViewPaintParts.ContentBackground);
e.Handled = true;
}
}
上面的代码非常简单 - 只需检查当前单元格是否在标题行中(具有 -1 索引)然后绘制除 ContentBackground 之外的所有内容。
我只在我的 Windows 7 机器上检查过它,它看起来不错,内容背景似乎仅用于排序字形 - 您需要在目标环境中对其进行测试以确保您没有需要做更多涉及的自定义绘画以保持 ContentBackground 没有字形。
标题单元格的宽度仍将包括字形空间。我通常会接受,因为改变它会变得有点混乱,但如果你必须让宽度适合文本,那么类似下面的东西会起作用。
首先在DataGridView的DataBindingComplete事件中设置宽度:
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
if (dataGridView1.AutoSizeColumnsMode == DataGridViewAutoSizeColumnsMode.AllCells)
{
// Loop over all the columns
foreach (DataGridViewColumn c in dataGridView1.Columns)
{
// Work out the size of the header text
Size s = TextRenderer.MeasureText(c.HeaderText, dataGridView1.Font);
// Change the autosize mode to allow us to see if the header cell has the
// longest text
c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
if (s.Width + 10 > c.Width)
{
// If the header cell is longest we set the column width
c.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
c.Width = s.Width + 10;
}
else
{
// If the header cell is not longest, reset the autosize mode
c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
}
}
}
完成此操作后,当单元格文本比标题长时,您仍需要允许列自动调整大小。
为此,我使用了CellValueChanged 事件:
void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
DataGridViewColumn c = dataGridView1.Columns[e.ColumnIndex];
if (c.AutoSizeMode == DataGridViewAutoSizeColumnMode.None)
{
Size s = TextRenderer.MeasureText(dataGridView1[e.ColumnIndex, e.RowIndex].Value.ToString(), dataGridView1.Font);
if (s.Width > c.Width)
{
c.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCellsExceptHeader;
}
}
}