Как нарисовать неактивные строки в столбце DataGridViewComboBox?

Я могу легко рисовать элементы в выпадающем списке DataGridViewComboBox. Но я не могу понять, как рисовать неактивные клетки в одном столбце.

Пример DataGridViewComboBox

Я видел, изучал и пробовал множество примеров для классического ComboBox, но я не понимаю всех аспектов DataGridViewComboBox.

В настоящее время у меня есть класс DataGridViewCustomPaintComboBox, полученный из DataGridViewComboBox. Каков минимальный набор переопределений для предоставления? Можете ли вы указать мне правильное направление?

2 ответа

Решение

Требуемый минимум для окрашивания неактивных клеток без фокуса CellTemplate назначение и Paint() переопределять:

public class DataGridViewCustomPaintComboBox : DataGridViewComboBoxColumn
{

    public DataGridViewCustomPaintComboBox()
    {
        base.New();
        CellTemplate = new DataGridViewCustomPaintComboBoxCell();
    }

}

public class DataGridViewCustomPaintComboBoxCell : DataGridViewComboBoxCell
{

    protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
    {
        // modify received arguments here
        base.Paint(...); // paint default parts (see paintParts argument)
        // add any custom painting here

    }

}

Обновление:

Пользовательский рисунок DataGridViewComboBox немного вовлечен. На самом деле он состоит из четырех разных случаев рисования:

Для несфокусированных ячеек вам нужно кодировать CellPainting событие:

private void dataGridView1_CellPainting(object sender, 
                                        DataGridViewCellPaintingEventArgs e)
{
   // drawstuff nr 1: draw the unfocused cell
}

Когда ячейка имеет фокус, фактическая DataGridViewComboBoxEditingControl (который является прямым потомком от ComboBox) создан и показан.

Вам нужно получить ручку к нему (в EditingControlShowing событие), а затем должны кодировать еще три случая в его DrawItem событие:

void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0)
    {
       // drawstuff 2: draw the undropped top portion
    }
    else
    {
       if ((e.State & DrawItemState.Selected) != DrawItemState.None
       {
          // drawstuff 3:  draw a selected item
       }
       else
       {
          // drawstuff 4:  draw an unselected item   
       }
    }
 }

Несколько заметок о различных кодах краски:

  • Drawstuff 1: Здесь вы должны нарисовать стрелку после рисования текста. Для этого лучше всего использовать ComboBoxRenderer.DrawDropDownButton метод. Вам нужно будет знать положение и размер, SystemInformation.VerticalScrollBarWidth должен помочь с этим.. обратите внимание, что TextRenderer.DrawText не только позволяет использовать хороший TextFormatFlags чтобы помочь с выравниванием, но и Backcolor!

  • Drawstuff 2: Обратите внимание, что ComboBox, к сожалению, не принимает BackColor своей ячейки. Это все равно поможет установить его, так что вы можете называть его целевым цветом. как в следующих кодах DARW вы хотите использовать комбинацию e.Graphics.DrawXxx звонки и TextRenderer.DrawText, Для облегчения ссылки на ячейки DGV, к которым он принадлежит, вы можете сохранить CurrentCell в ссылке ComboBox"s Tag при настройке в EditingControlShowing событие.

  • Drawstuff 3: выбранный элемент может иметь специальные цвета для шрифта и фона

  • Drawstuff 4: обычная вещь, это просто: довольно обычный


Код ниже - оригинальная версия моего ответа, охватывающая только случаи 3 и 4:

Вот короткий пример, чтобы показать вам, как нарисовать DataGridViewComboBox, Обратите внимание, что я показываю только минимум и не занимаюсь раскрашиванием цветных квадратов..:

Начнем с определения ссылки на уровень класса на ячейку:

ComboBox theBoxCell = null;

в EditingControlShowing мы устанавливаем ссылку, добавляем обработчик события и устанавливаем его в режим рисования владельцем:

private void dataGridView1_EditingControlShowing(object sender,
             DataGridViewEditingControlShowingEventArgs e)
{
    theBoxCell = (ComboBox) e.Control;
    theBoxCell.DrawItem += theBoxCell_DrawItem;
    theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}

Наконец мы добавляем код рисования:

void theBoxCell_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0) return;
    string t = theBoxCell.Items[e.Index].ToString();
    using (SolidBrush brush = new SolidBrush(
        (e.State & DrawItemState.Selected) != DrawItemState.None ?
                   Color.LightCyan : Color.LightGray))
        e.Graphics.FillRectangle(brush, e.Bounds);
    e.DrawFocusRectangle();
    e.Graphics.DrawString(t, Font, Brushes.DarkGoldenrod, e.Bounds.X + 6, e.Bounds.Y + 1);

}

Мы могли бы также добавить код отрисовки в linq к подключению события..

Вот результат:

Другие вопросы по тегам