如何格式化 DataGridViewComboBoxColumn 中 ComboBox 中的特定项目?
How to format a specific item in the ComboBox in a DataGridViewComboBoxColumn?
我在(重新)创建 DataGridView 中的列的方法中有与此类似的代码:
MyColumn = new DataGridViewComboBoxColumn()
{
Name = "..",
HeaderText = "..",
SortMode = DataGridViewColumnSortMode.NotSortable
};
MyColumn.Items.Clear();
foreach (string s in MyStringList)
{
MyColumn.Items.Add(s);
}
MyColumn.Items.Add("");
// I would like this empty string to be shown as "No group"
// with an italic grayed out font
我想我可能必须为列中 ComboBox-es 的项目创建一个 class,我应该在其中覆盖 ToString()
方法,但我想知道如何格式化 No Group
项。
一个相关的问题是 here,它是关于不在 DataGridView 内部的普通 ComboBox,答案是使用 DrawMode
属性和 DrawItem
事件解决问题 ComboBox
class.
要自定义绘制 ComboBox
,您需要处理 EditingControlShowing
,然后获取 EditingControl
即 DataGridViewComboBoxEditingControl
,然后设置其 DrawMode
OwnerDrawFixed
并处理其 DrawItem
事件。
要自定义绘制单元格,您需要处理 CellPainting
事件并为单元格样式设置不同的字体和颜色,让绘制继续使用新值。如果需要,您也可以绘制整个单元格。
例子
加载示例数据:
private DataTable LoadProducts()
{
var dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("CategoryId", typeof(int));
dt.Rows.Add("P1", 1);
dt.Rows.Add("P2", 1);
dt.Rows.Add("P3", DBNull.Value);
return dt;
}
private DataTable LoadCategories()
{
var dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name");
dt.Rows.Add(DBNull.Value, "No Category");
dt.Rows.Add(1, "C1");
dt.Rows.Add(2, "C2");
dt.Rows.Add(2, "C3");
return dt;
}
设置 DataGridView 列:
private void Form1_Load(object sender, EventArgs e)
{
var products = LoadProducts();
var categories = LoadCategories();
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()
{
Name = "NameColumn",
DataPropertyName = "Name",
HeaderText = "Name"
});
dataGridView1.Columns.Add(new DataGridViewComboBoxColumn()
{
Name = "CategoryIdColumn",
DataPropertyName = "CategoryId",
HeaderText = "Category",
DataSource = categories,
ValueMember = "Id",
DisplayMember = "Name",
DisplayStyle= DataGridViewComboBoxDisplayStyle.Nothing
});
dataGridView1.DataSource = products;
dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;
dataGridView1.CellPainting += DataGridView1_CellPainting;
}
处理编辑控件显示
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1?.CurrentCell?.OwningColumn?.Name != "CategoryIdColumn")
return;
var combo = e.Control as DataGridViewComboBoxEditingControl;
if (combo == null)
return;
combo.DrawMode = DrawMode.OwnerDrawFixed;
combo.DrawItem += (obj, args) =>
{
var txt = args.Index >= 0 ? combo.GetItemText(combo.Items[args.Index]) : "";
var textColor = args.Index == 0 ? SystemColors.GrayText : SystemColors.ControlText;
var font = args.Index == 0 ? new Font(combo.Font, FontStyle.Italic) : combo.Font;
if ((args.State & DrawItemState.Selected) == DrawItemState.Selected)
{
textColor = SystemColors.HighlightText;
}
args.DrawBackground();
TextRenderer.DrawText(args.Graphics, txt, font,
args.Bounds, textColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left);
};
}
处理单元格绘画
private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0 ||
dataGridView1.Columns[e.ColumnIndex].Name != "CategoryIdColumn")
return;
if (dataGridView1[e.ColumnIndex, e.RowIndex].Value == DBNull.Value)
{
e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Italic);
e.CellStyle.ForeColor = SystemColors.GrayText;
}
else
{
e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Regular);
e.CellStyle.ForeColor = SystemColors.ControlText;
}
}
我在(重新)创建 DataGridView 中的列的方法中有与此类似的代码:
MyColumn = new DataGridViewComboBoxColumn()
{
Name = "..",
HeaderText = "..",
SortMode = DataGridViewColumnSortMode.NotSortable
};
MyColumn.Items.Clear();
foreach (string s in MyStringList)
{
MyColumn.Items.Add(s);
}
MyColumn.Items.Add("");
// I would like this empty string to be shown as "No group"
// with an italic grayed out font
我想我可能必须为列中 ComboBox-es 的项目创建一个 class,我应该在其中覆盖 ToString()
方法,但我想知道如何格式化 No Group
项。
一个相关的问题是 here,它是关于不在 DataGridView 内部的普通 ComboBox,答案是使用 DrawMode
属性和 DrawItem
事件解决问题 ComboBox
class.
要自定义绘制 ComboBox
,您需要处理 EditingControlShowing
,然后获取 EditingControl
即 DataGridViewComboBoxEditingControl
,然后设置其 DrawMode
OwnerDrawFixed
并处理其 DrawItem
事件。
要自定义绘制单元格,您需要处理 CellPainting
事件并为单元格样式设置不同的字体和颜色,让绘制继续使用新值。如果需要,您也可以绘制整个单元格。
例子
加载示例数据:
private DataTable LoadProducts()
{
var dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("CategoryId", typeof(int));
dt.Rows.Add("P1", 1);
dt.Rows.Add("P2", 1);
dt.Rows.Add("P3", DBNull.Value);
return dt;
}
private DataTable LoadCategories()
{
var dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name");
dt.Rows.Add(DBNull.Value, "No Category");
dt.Rows.Add(1, "C1");
dt.Rows.Add(2, "C2");
dt.Rows.Add(2, "C3");
return dt;
}
设置 DataGridView 列:
private void Form1_Load(object sender, EventArgs e)
{
var products = LoadProducts();
var categories = LoadCategories();
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn()
{
Name = "NameColumn",
DataPropertyName = "Name",
HeaderText = "Name"
});
dataGridView1.Columns.Add(new DataGridViewComboBoxColumn()
{
Name = "CategoryIdColumn",
DataPropertyName = "CategoryId",
HeaderText = "Category",
DataSource = categories,
ValueMember = "Id",
DisplayMember = "Name",
DisplayStyle= DataGridViewComboBoxDisplayStyle.Nothing
});
dataGridView1.DataSource = products;
dataGridView1.EditingControlShowing += DataGridView1_EditingControlShowing;
dataGridView1.CellPainting += DataGridView1_CellPainting;
}
处理编辑控件显示
private void DataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dataGridView1?.CurrentCell?.OwningColumn?.Name != "CategoryIdColumn")
return;
var combo = e.Control as DataGridViewComboBoxEditingControl;
if (combo == null)
return;
combo.DrawMode = DrawMode.OwnerDrawFixed;
combo.DrawItem += (obj, args) =>
{
var txt = args.Index >= 0 ? combo.GetItemText(combo.Items[args.Index]) : "";
var textColor = args.Index == 0 ? SystemColors.GrayText : SystemColors.ControlText;
var font = args.Index == 0 ? new Font(combo.Font, FontStyle.Italic) : combo.Font;
if ((args.State & DrawItemState.Selected) == DrawItemState.Selected)
{
textColor = SystemColors.HighlightText;
}
args.DrawBackground();
TextRenderer.DrawText(args.Graphics, txt, font,
args.Bounds, textColor,
TextFormatFlags.VerticalCenter | TextFormatFlags.Left);
};
}
处理单元格绘画
private void DataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0 ||
dataGridView1.Columns[e.ColumnIndex].Name != "CategoryIdColumn")
return;
if (dataGridView1[e.ColumnIndex, e.RowIndex].Value == DBNull.Value)
{
e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Italic);
e.CellStyle.ForeColor = SystemColors.GrayText;
}
else
{
e.CellStyle.Font = new Font(e.CellStyle.Font, FontStyle.Regular);
e.CellStyle.ForeColor = SystemColors.ControlText;
}
}