Как нарисовать неактивные строки в столбце 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
"sTag
при настройке в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 к подключению события..
Вот результат: