| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C++ Builder > Мерцание StringGrid при определении OnDrawCell |
| Автор: Нитонисе 11.10.2013, 16:33 |
| Если определить обработчик OnDrawCell, то при перерисовке грида происходит заметное мерцание. Например я просто щелкаю мышкой по разным ячейкам и после каждого щелчка видно как грид перерисовывается. Если же этот обработчик не определять, то такое мерцание если и имеет место быть, то в гораздо меньшей степени. С чем это связано? Такое ощущение, что если не определить OnDrawCell, то грид не полностью перерисовывается при том же кликании по ячейкам мышью, а рисуются заново лишь те ячейки, по которым кликаю. |
| Автор: sawfish 11.10.2013, 19:40 |
| Если при не определении обработчика OnDrawCell мерцание всё равно остается, то дело не в OnDrawCell. Проверьте, нет ли где-нибудь лишних Repaint или Refresh. |
| Автор: sawfish 14.10.2013, 08:24 |
| Я вообще обработчик OnMouseDown не трогаю, всё должно прекрасно отрисовываться без него Repaint у StringGrid'а в моей проге вызывается только в трех случаях: - при изменении размеров окна - при условии отображения выделения цветом (моя настройка в проге) - в обработчике OnTopLeftChanged (у меня там строки разной высоты + объединение ячеек) |
| Автор: sawfish 16.10.2013, 11:47 |
| Нитонисе, справились с мерцанием? |
| Автор: Нитонисе 16.10.2013, 21:19 | ||
Да. Сделал новый класс, наследник от StringGrid, в котором открыл функцию родительского класса InvalidateRow. Она перерисовывает строку грида. Перерисовку выполняю на OnSelectCell - перерисовываются строка, в которой выбрана ячейка и та строка, которая была выбрана до этого. Это позволило убрать в обработчиках метод стринггрида Refresh, который перерисовывал грид полностью. Но эти манипуляции мерцание до конца не прибыли. Последний удар был нанесен выставлением свойства DoubleBuffered в true. В коде SGLoads - это компонент класса TAdvStringGrid.
|
| Автор: sawfish 17.10.2013, 07:51 | ||
| Жесть! А что так сложно-то? Не, правда, я не понимаю, из-за чего у вас там такие сложности... Вот мой тестовый пример. На форме StringGrid, CheckBox и RadioGroup.
Ничего не мерцает. ![]() |
| Автор: Нитонисе 18.10.2013, 22:52 | ||
Ну, во-первых у вас пример немного неправильный. У меня при выделении строки непосредственно выделенная ячейка закрашивается темным цветом, а все остальные ячейки этой же строки - светлоголубым. Как на моих скриншотах выше. При этом свойство goRowSelect = false. При этом, нужно чтобы отрисовка корректно работала при любых способах навигации по гриду (мышью или с клавиатуры). Ну и во-вторых - я использую не родной грид, а из набора компонентов TMS. Там этот грид называется TAdvStringGrid. |
| Автор: sawfish 20.10.2013, 17:16 | ||||||||
А что мешает сделать проверку и подставить нужный цвет ячейки в нужной строке в моем примере?
Эмм... ну у меня тоже какбэ, просто можно менять в ходе отображения.
Прекрасно работает!
С этого нужно было начинать свой первый пост. |
| Автор: Нитонисе 20.10.2013, 18:44 | ||||
Так у вас такого функционала в принципе нет
И что? Ну поставили в false - и картина выглядит совсем не так как надо. Не будет работать, если вы выполните все условия. |
| Автор: sawfish 21.10.2013, 10:35 | ||||
| (Лирическое отступление. На моем рабочем мониторе не видны светло-голубые ячейки строки на картинке...) Итак, на форме TStringGrid, и заведена переменная iRow для запоминания индекса строки, на которой выделена ячейка. goRowSelect = false goRangeSelect = false
![]() Мерцания нет, хоть с DoubleBuffered = true, хоть DoubleBuffered = false.
Не знаю, все ли ваши условия выполнены, но прекрасно работает и при навигации клавиатурой! На TAdvStringGrid не тестировалось. |
| Автор: Нитонисе 21.10.2013, 11:26 | ||
Дело ведь не в конкретном цвете, а в принципе. Закрашиваем своими цветами активную строку и активную ячейку. В вашем примере принцип реализован, но заметно отчетливое мерцание. В этом повинен метод Repaint. Если выставить DoubleBuffered = true - мерцания пропадает. В принципе и у меня можно было бы использовать связку метода Repaint и свойства DoubleBuffered и обойтись без создания класса THackGrid. На малых сетках разницы подозреваю не будет вообще. Но все ж THackGrid с его функцией перерисовки только двух строк, вместо всей сетки - более экономичен. И чем больше по размерам сетка - тем больше этот эффект экономности |
| Автор: sawfish 21.10.2013, 16:56 |
| Не люблю создавать и переопределять классы там, где это делается для чего-то малого и несущественного. Если это малое и несущественное создает трудности (условно), несоизмеримые с его реализацией, это отбрасывается или пересматривается. Например, можно было бы всего лишь закрашивать четные и нечетные строки разными цветами, а выделенная ячейка оставалась бы выделенной (без привязки к строке), и лишних Repaint'ов не было бы: ![]() ИМХО |
| Автор: Нитонисе 24.10.2013, 12:12 | ||
Да особой пользы от моего класса и нету. Весь смысл от него - использовать метод InvalidateRow, который перерисовывает ряд. Но даже с таким подходом сетка мерцает и я все равно выставил DoubleBuffered = true. И в таком случае можно обойтись без этого нового класса и не пользоваться InvalidateRow, а использовать стандартный Repaint - сетка все равно мерцать не будет, так как DoubleBuffered = true. Я просто оставил этот класс потому что он появился хронологически раньше идеи установки DoubleBuffered = true и я просто не стал его уже удалять А ваша идея с разноцветными строчками - мне такой дизайнерский подход не очень нравится |