Популярный способ (1, 2) для пользовательской окраски предметов в DataGridViewComboBox - это обработка события DataGridView1. EditingControlShowing и наладка DrawItem обработчики событий там:Как сделать пользовательский DataGridViewComboBox зависимым только от его DataGridViewComboBoxColumn?
private void dataGridView1_EditingControlShowing(
object sender,
DataGridViewEditingControlShowingEventArgs e)
{
theBoxCell = (ComboBox) e.Control;
theBoxCell.DrawItem += theBoxCell_DrawItem;
theBoxCell.DrawMode = DrawMode.OwnerDrawVariable;
}
Вы видите, что это не так: она использует событие контроля уровня осуществлять работу по столбцам. Но что, если у меня есть 50+ datagridviews? Покраска пользовательских комбинированных ящиков должна обрабатываться за экземпляр колонки, оставив контрольный уровень неповрежденным.
Минимальная реализация обработки столбцов ниже. Единственная проблема, с которой я столкнулся, заключается в том, что метод OnDrawItem()
не вызван. Что мне не хватает? (Вы можете видеть, что фуксии фона переопределение от того же класса работает.)
(Чтобы воспроизвести, просто вставьте следующий код в файл класса и добавить столбец типа DataGridViewCustomPaintComboBoxColumn к вашим dataGridView1.)
public class DataGridViewCustomPaintComboBoxColumn : DataGridViewComboBoxColumn
{
public DataGridViewCustomPaintComboBoxColumn()
{
base.New();
CellTemplate = new DataGridViewCustomPaintComboBoxCell();
}
}
public class DataGridViewCustomPaintComboBoxCell : DataGridViewComboBoxCell
{
public override Type EditType {
get { return typeof(DataGridViewCustomPaintComboBoxEditingControl); }
}
protected override void Paint(...)
{
//painting stuff for incative cells here - works well
}
}
public class DataGridViewCustomPaintComboBoxEditingControl : DataGridViewComboBoxEditingControl
{
public override Color BackColor { // property override only for testing
get { return Color.Fuchsia; } // test value works as expected
set { base.BackColor = value; }
}
protected override void OnPaint(PaintEventArgs e) // never called - why?
{
base.OnPaint(e)
}
protected override void OnDrawItem(DrawItemEventArgs e) // never called - why?
{
base.OnDrawItem(e)
}
}
Я понимаю вашу идею статического декоратора, но прежде чем принять ответ, я не уверен в ваших рассуждениях. Как вы говорите, «DataGridViewComboBoxCell» не является элементом управления. Он используется для рисования реплик элемента управления в неактивных ячейках (и служит одному экземпляру управления для редактируемой ячейки). Таким образом, переопределение своего события 'OnPaint()' работает, как ожидалось (я расширил указанный выше источник). OTOH 'DataGridViewComboBoxEditingControl' * - это элемент управления (прямой потомок' ComboBox'), поэтому, когда его экземпляр создан для использования с событием 'EditingControlShowing', его переопределенные' OnPaint() 'и' ItemDraw() 'должны работать, нет? – miroxlav
Да, я думаю, вы все поняли, за исключением того, что я не уверен, что события Paint/OnPaint вступят в силу или даже начнут стрелять; они заменяются событием DrawItem/OnDrawItem. Чтобы нарисовать часть, которая не выпала, вам нужно проверить «e.Index == -1». – TaW
На данный момент я не уверен, правильно ли мы думаем. Мне нужно подтвердить. Мои пункты: Во-первых: [источник ссылки для DataGridViewComboBoxEditingControl.cs] (http://bit.ly/1Ojc1Zl) делает * не * показывает какие-либо манипуляции с его предшественником ComboBox. (Без отключения материала рисования и т. Д.). Второе: переопределение 'OnPaint()' и 'OnDrawItem()' does * not * работают даже со стандартным простым 'ComboBox'. Поэтому, возможно, после того, как вы узнаете, как правильно создавать выпадающие на заказ выпадающие списки, никакой декоратор не может потребоваться - просто правильно написанный потомок 'DataGridViewComboBoxEditingControl' :). Позвольте мне проверить, что ... – miroxlav