Как отформатировать конкретный элемент в ComboBox в DataGridViewComboBoxColumn? - PullRequest
0 голосов
/ 01 января 2019

У меня есть код, подобный этому, в методе, который (повторно) создает столбцы в 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-ов встолбец, в котором я должен переопределить метод ToString(), но я хочу знать, как отформатировать элемент No Group.

Смежный вопрос: здесь , что ообычный ComboBox, не входящий в DataGridView, с решением проблемы, используя свойство DrawMode prperty и DrawItem класса ComboBox.

1 Ответ

0 голосов
/ 01 января 2019

Для пользовательской раскраски ComboBox вам нужно обработать EditingControlShowing, а затем получить EditingControl, равный DataGridViewComboBoxEditingControl, а затем установить его DrawMode в OwnerDrawFixed и обработать его событие DrawItem.

Для пользовательской раскраски ячейки необходимо обработать событие CellPainting, задать другой шрифт и цвет для стилей ячейки и позволить рисованию продолжить с новыми значениями.Вы также можете нарисовать всю ячейку, если хотите.

enter image description here

Пример

Загрузить образецДанные:

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

Обработка редактированияControlShowing

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

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