我正在为我的 C# 项目中的 DataGridView 设置以下属性 ...
sampleDataGridView.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
sampleDataGridView.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
但我注意到标题的(即标题单元格中的文本由于某种原因略微向左偏移......虽然数据行完全居中对齐......
什么原因造成的?
因为有一个排序字形(小箭头),DataGridView为此保留了一些空间来显示排序顺序。如果您想禁用排序字形,请将列上的 SortMode 设置为 NotSortable,然后您的文本应该居中。
老话题,
我有这个问题,我发现问题是我有网格数据源链接到我的东西,当创建列时,他们默认打开允许排序,这创建了向下箭头按钮进行排序,文本被推到左边。 对此的小修复是:
private void MyDataGridView_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
{
e.Column.SortMode = DataGridViewColumnSortMode.NotSortable;
}
我遇到了和你一样的问题,这似乎是一个框架问题:MS Connect
计算出没有反射的字形宽度,并在越界时抑制:
在下面的代码中,我打开和关闭排序,同时将列宽自动调整为列标题文本宽度。排序开/关之间的宽度差异将显示列排序字形使用的宽度。
当列宽设置为小于自动调整宽度时,列会丢失字形,我通过插入对称的左右列填充来抑制它。
我还使用字典存储 ColumnWidth 事件,通过 datagridview 实例在设置宽度时打开和关闭宽度事件。
我称这个疯狂的代码既可以自动调整初始列宽,也可以在用户拖动列宽时管理列标题填充。
void AdaptColumnHeaderText(DataGridViewColumn column, bool autoSize=false)
{
//Supress column width events
if (dataGridViewColumnWidthEventHandlers.ContainsKey(column.DataGridView))
{
dataGridView1.ColumnWidthChanged -= dataGridViewColumnWidthEventHandlers[column.DataGridView];
}
//Save initial column with as preferred
var w_preferred = column.Width;
if (
column.SortMode.Equals(DataGridViewColumnSortMode.Automatic) &&
column.HeaderCell.Style.Alignment.Equals(DataGridViewContentAlignment.MiddleCenter))
{
//remove all header padding
column.HeaderCell.Style.Padding = new Padding(0, 0, 0, 0);
//Fit column width to header text with AND sort glyph
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader;
//save column width sort enabled
var w_sort = column.Width;
//Fit column width to header text with NO sort glyph
column.SortMode = DataGridViewColumnSortMode.NotSortable;
//save column width when sort disable
var w_nosort = column.Width;
//Calculate width consumed by sort glyph
var w_glyph = w_sort - w_nosort;
//Nominal column width if glyph width applied left and right of header text
var w_nominal = w_glyph + w_nosort + w_glyph;
//Disable column width autosize
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
//Enable column autosorting
column.SortMode = DataGridViewColumnSortMode.Automatic;
//If autosize option - ignore preferred width and set to nominal
if (autoSize)
{
w_preferred = w_nominal;
}
//Pad depending on final column width
if (w_preferred >= w_nominal)
{
//Preferred width greater than nominal - pad left of text to balance width used by glyph
column.HeaderCell.Style.Padding = new Padding(w_glyph, 0, 0, 0);
}
else
{
//Two symetric glyphs will not fit - pad left and right to supress glyph
w_glyph = (w_preferred - w_nosort) / 2;
column.HeaderCell.Style.Padding = new Padding(w_glyph, 0, w_glyph, 0);
}
column.Width = w_preferred;
Console.WriteLine("name:{0}, glyph:{1}, w_preferred:{2}", column.Name, w_glyph, w_preferred);
}
//re-enable column width events
if (dataGridViewColumnWidthEventHandlers.ContainsKey(column.DataGridView))
{
dataGridView1.ColumnWidthChanged += dataGridViewColumnWidthEventHandlers[column.DataGridView];
}
}
您可以在列名称的开头添加两个空格以补偿为字形保留的空间。
我知道这个问题已经有 10 多年的历史了,但我想在这里提出我的解决方案,希望其他人可能想要一个快速的代码障碍来使用我的可行解决方案。
DataGridView 上的列标题总是偏离中心,因为“隐藏的”排序字形仅在您单击该列以对列进行排序时(使用默认设置)才显示为右侧的箭头。当尝试将标题文本对齐为
DataGridViewContentAlignment.MiddleCenter
时,由于缺少字形,它看起来并没有真正居中。
我使用 DataGridView 中的所有设置手动绘制列标题,除了在未显示时忽略字形大小并在显示时尊重它们(在对列进行排序之后)。
private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
DataGridView dgv = sender as DataGridView;
SortOrder sort = dgv.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection;
if (e.RowIndex == -1 && sort == SortOrder.None)
{
string headerText = dgv.Columns[e.ColumnIndex].HeaderText;
Font headerFont = e.CellStyle.Font;
Brush headerBrush = new SolidBrush(e.CellStyle.ForeColor);
DataGridViewContentAlignment headerAlignment = e.CellStyle.Alignment;
e.Paint(e.ClipBounds, (DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground));
SizeF stringSize = TextRenderer.MeasureText(e.Graphics, headerText, e.CellStyle.Font, e.CellBounds.Size);
Rectangle p = e.CellBounds;
switch (headerAlignment)
{
case DataGridViewContentAlignment.TopCenter:
p.Offset(
e.CellBounds.Width / 2 - (int)(stringSize.Width / 2),
0
);
break;
case DataGridViewContentAlignment.TopRight:
p.Offset(
e.CellBounds.Width - (int)stringSize.Width,
0
);
break;
case DataGridViewContentAlignment.MiddleLeft:
p.Offset(
0,
e.CellBounds.Height / 2 - (int)(stringSize.Height / 2)
);
break;
case DataGridViewContentAlignment.MiddleCenter:
p.Offset(
e.CellBounds.Width / 2 - (int)(stringSize.Width / 2),
e.CellBounds.Height / 2 - (int)(stringSize.Height / 2)
);
break;
case DataGridViewContentAlignment.MiddleRight:
p.Offset(
e.CellBounds.Width - (int)stringSize.Width,
e.CellBounds.Height / 2 - (int)(stringSize.Height / 2)
);
break;
case DataGridViewContentAlignment.BottomLeft:
p.Offset(
0,
e.CellBounds.Height - (int)stringSize.Height
);
break;
case DataGridViewContentAlignment.BottomCenter:
p.Offset(
e.CellBounds.Width / 2 - (int)(stringSize.Width / 2),
e.CellBounds.Height - (int)stringSize.Height
);
break;
case DataGridViewContentAlignment.BottomRight:
p.Offset(
e.CellBounds.Width - (int)stringSize.Width,
e.CellBounds.Height - (int)stringSize.Height
);
break;
default:
p.Offset(
0,
0
);
break;
}
e.Graphics.DrawString(headerText, headerFont, headerBrush, new PointF(p.X, p.Y));
e.Handled = true;
}
}