2016-07-09 2 views
2

У меня есть TStringGrid, чьи ячейки получают пользовательский цвет фона, используя событие OnDrawCell. Теперь я хотел бы визуально расширить каждую строку до правого конца сетки ClientRect, т. Е. Удалить пробелы, где больше нет столбцов.Как нарисовать вне ячейки в TStringGrid.OnDrawCell?

Я рассмотрел использование дополнительного столбца «фантом» и постоянную настройку его ColWidth, но этот хак не очень хорошо работает с сетками, которые несколько неудобны по вертикальной прокрутке. Моим предпочтительным решением было бы просто нарисовать эту область.

Вычисление соответствующего прямоугольника легко, но то, что я рисую, сразу же стирается. Я отключил DefaultDrawing и удалил все опции goFixedVertLine, goFixedHorzLine, goVertLine и goHorzLine, но не имеет значения.

Вот некоторые примеры кода:

LGrid := TStringGrid(Sender); 
LGrid.Canvas.Brush.Color := clYellow + 1000 * (1 + ARow); 
if ACol = LGrid.ColCount - 1 then 
    Rect.Right := LGrid.ClientRect.Right; // Doesn't have any effect 
LGrid.Canvas.FillRect(Rect); 

Что это самый простой способ добиться того, что приведенный выше код предназначен? Я надеюсь, что это возможно, чтобы рисовать там без написания класса interposer, переопределяя метод Paint и реализуя большую часть того, что уже доступно мне, используя это событие.

ответ

1

VCL заполняет пустую область, не занятую ячейками, после того как чертеж ячеек завершен. Вот почему твоя картина перечеркнута. Можно предотвратить то, что вы нарисовываете, удаляясь мгновенно с помощью обработчика событий OnDrawCell, не нужно переопределять Paint или получить новый элемент управления.

Поскольку VCL использует тот же контекст устройства для рисования ячеек и пустой области, вы можете вырезать прямоугольник расширения, который вы только что извлекли из контекста устройства, а ОС не будет игнорировать последующие вызовы VCL для этой зоны.

LGrid := TStringGrid(Sender); 
LGrid.Canvas.Brush.Color := clYellow + 1000 * (1 + ARow); 
if ACol = LGrid.ColCount - 1 then 
    Rect.Right := LGrid.ClientRect.Right; 
LGrid.Canvas.FillRect(Rect); 
ExcludeClipRect(LGrid.Canvas.Handle, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom); // <-- 
+0

Хотя 'ExcludeClipRect', конечно, останавливает эту область от стирания - я чему-то научился :) - к сожалению, общий результат не так, как я надеялся. Область, которую я могу теперь успешно рисовать, не перерисовывается при изменении выбора или изменения размера. Возможно, в еще большем числе случаев. Не уверен, что решение вопроса, которое входит в сферу этого вопроса. –

+0

@Thijs - OnDrawCell, вероятно, не вызывается при изменении размера (увеличение пустой области). В этом случае я не думаю, что можно было бы включить вмешательство в OnDrawCell. Я не могу догадаться, почему выбор не работает, хотя ... –

+0

Чтобы перекрасить, вы можете использовать события OnResize, OnSelectCell и OnTopLeftChanged для ручного 'Invalidate()' всей сетки или просто ' InvalidateRect() 'желаемый раздел (разделы). –

Смежные вопросы