Как я уже говорил в прошлой теме об этой теме, OnPaint()
и UserPaint
не работают с ListView. Картина обрабатывается базовым элементом управления и не может быть перехвачена таким образом. Это отличается от других элементов управления
Итак, когда ControlStyles.UserPaint
равно true
, базовому элементу управления не предписано перерисовывать себя. Вместо этого весь рисунок перенаправляется на методы OnPaintBackground()
и OnPaint()
, которые, как вы обнаружили, ничего не делают.
Есть два способа сделать то, что вы просили (второй лучше первого):
Первый способ: перехватить WM_PAINT
, выполнить базовую обработку, а затем нарисовать в виде списка. Примерно так:
public class MyListView : ListView
{
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case 0x0F: // WM_PAINT
this.HandlePaint(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
protected virtual void HandlePaint(ref Message m) {
base.WndProc(ref m);
using (Graphics g = this.CreateGraphics()) {
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
sf.Trimming = StringTrimming.EllipsisCharacter;
g.DrawString("Some text", new Font("Tahoma", 13),
SystemBrushes.ControlDark, this.ClientRectangle, sf);
}
}
}
Но это создает проблемы с перерисовкой, когда то, что вы рисуете, находится вне области, в которой, по мнению списка, содержится содержимое элемента управления - оно не вызывает события рисования.
Второй способ: перехватить уведомление CustomDraw (это , а не то же, что OwnerDraw) и прослушать этап CDDS_POSTPAINT
. На этом этапе вы можете смело рисовать в виде списка. Вы можете посмотреть код ObjectListView , чтобы увидеть, как это делается.
Вы также можете просто избавить себя от лишних хлопот и напрямую использовать ObjectListView:)