【问题标题】:How to format a specific item in the ComboBox in a DataGridViewComboBoxColumn?如何格式化 DataGridViewComboBoxColumn 中 ComboBox 中的特定项目?
【发布时间】:2019-05-28 11:06:56
【问题描述】:

我在(重新)创建 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 项目。

一个相关的问题是here,这是一个关于不在 DataGridView 内的普通 ComboBox,答案使用 DrawMode prperty 和 DrawItem 类的 ComboBox 事件解决问题。

【问题讨论】:

  • 为什么不MyColumn.Items.Add("No Group");
  • 感谢您的评论。我将问题更新为“无组”作为我要格式化的文本。
  • MyColumn.DisplayStyleDropDownButton 所以你应该能够使用 ComboBoxRenderer 类作为 DrawDropDownButton 在这里解释stackoverflow.com/a/7486187/2516718
  • @derloopkat 谢谢。这部分解决了我的问题,但我正在寻找一种方法来在 ComboBox 列中绘制 ComboBox-es 的下拉菜单,除了绘制封闭的 ComboBox-es。

标签: c# .net winforms datagridview datagridviewcolumn


【解决方案1】:

要自定义绘制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;
}

处理 EditingControlShowing

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);
    };
}

处理 CellPainting

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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 2014-11-16
    相关资源
    最近更新 更多