C# 如何格式化DataGridViewComboBoxColumn中ComboBox中的特定项?

C# 如何格式化DataGridViewComboBoxColumn中ComboBox中的特定项?,c#,.net,winforms,datagridview,datagridviewcolumn,C#,.net,Winforms,Datagridview,Datagridviewcolumn,我在(重新)创建DataGridView中的列的方法中有类似的代码: MyColumn = new DataGridViewComboBoxColumn() { Name = "..", HeaderText = "..", SortMode = DataGridViewColumnSortMode.NotSortable }; MyColumn.Items.Clear(); foreach (string s in MyStringList) {

我在(重新)创建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的项创建一个类,在该类中我应该重写
ToString()
方法,但我想知道如何格式化
No Group


一个相关的问题是关于不在DataGridView中的普通组合框的问题,答案是使用
ComboBox
类的
DrawMode
属性和
DrawItem
事件来解决问题。

对于自定义绘制
ComboBox
,您需要处理
editingcontrolshow
,然后获取
EditingControl
,即
DataGridViewComboBoxEditingControl
,然后将其
DrawMode
设置为
OwnerDrawFixed
并处理其
DrawItem
事件

对于自定义绘制单元格,您需要处理
CellPainting
事件,为单元格样式设置不同的字体和颜色,并让绘制以新值继续。如果需要,也可以绘制整个单元格

示例

加载样本数据:

设置DataGridView列:

句柄编辑控件显示

手绘

private void DataGridView1\u CellPainting(对象发送方,DataGridViewCellPaintingEventArgs e)
{
如果(e.ColumnIndex<0 | | e.RowIndex<0||
dataGridView1.Columns[e.ColumnIndex].Name!=“CategoryIdColumn”)
返回;
如果(dataGridView1[e.ColumnIndex,e.RowIndex].Value==DBNull.Value)
{
e、 CellStyle.Font=新字体(e.CellStyle.Font,FontStyle.Italic);
e、 CellStyle.ForeColor=SystemColors.GrayText;
}
其他的
{
e、 CellStyle.Font=新字体(如CellStyle.Font、FontStyle.Regular);
e、 CellStyle.ForeColor=SystemColor.ControlText;
}
}

Why not
MyColumn.Items.Add(“无组”)?感谢您的评论。我更新了问题,将“无组”作为我想要格式化的文本。
MyColumn.DisplayStyle
DropDownButton
,因此您应该能够使用
ComboBoxRenderer
类来处理
DrawDropDownButton
,如这里所述@derloopkat谢谢。这部分解决了我的问题,但我正在寻找一种方法,除了绘制闭合的组合框外,还可以在组合框列中绘制组合框的下拉菜单。
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;
}
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;
    }
}