Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения
KANSoftWare

Грид с объединяемыми ячейками данных

Delphi , Компоненты и Классы , TStringGrid и TDrawGrid

Грид с объединяемыми ячейками данных

Оформил: DeeCo

Автор: Михаил Зайкин

1. Что было нужно.

По ходу выполнения проекта встала следующая задача: обеспечить ввод данных в таблицу, с возможностью визуально объединить/сгруппировать ячейки данных. Так как даже для одной задачи могут быть различные требования к представлению данных, грид должен как можно гибче взаимодействовать с пользователем.

Опробовав замечательные MSHFlexGrid, ObjectiveGrid и получив пару десятков вопросов “а почему…”, “а как..”, и замечаний “а вотя я …, а он не…” решено было, что пусть грид будет поглупее, попроще, зато пользователь будет в полной мере контролировать структуру таблицы.

2. Что было сделано.

Определены типы объединения: TMergeMode=(mmNone,mmByCol,mmByRow,mmFree);
  • mmNone – объединение не производится, MergeCells всегда возвращает nil
  • mmByCol – объединяются клетки внутри одного столбца, из заданного для объединения диапазона используется его левая часть
  • mmByRow – объединяются клетки внутри одной строки, из заданного для объединения диапазона используется его верхняя часть
  • mmFree - объединяются клетки в любых диапазонах

Определен класс-диапазон:

TMZRange = class(TObject)
private
  FOwner: TMZMergeStringGrid;
  FRect: TGridRect;
  function GetValue: string;
  procedure SetValue(Value: string);
public
  constructor Create(AOwner: TMZMergeStringGrid;
    Range: TGridRect);
  function Contain(ACol, ARow: integer): boolean; overload;
  function Contain(ARect: TGridRect): boolean; overload;
  function Intersect(ARect: TGridRect): boolean;
  function Visible: boolean;
  function VisibleRect: TGridRect;
  property Rect: TGridRect read FRect;
  property Value: string read GetValue write SetValue;
end;
Небольшие пояснения:
  • Contain – содержит ли внутри клетку (диапазон)
  • Intersect – пересекается ли с диапазоном
  • Value – значение. В качестве оного используется значение левой верхней клетки. Данные в остальных клетках не изменяются.
  • VisibleRect – видимая часть диапазона
Остальное, думаю, понятно.
Определен, собственно, грид: TMZMergeStringGrid = class(TStringGrid)

Часть полей и функций была напрямую скопирована из приватной секции TCustomGrid.

Добавлены public функции и свойства:
function MergeCells(ARect:TGridRect):TMZRange
– пытается произвести объединение заданного диапазона и возвращает указатель в случае успеха и nil в противном случае.
Отказ функции может быть в следующих случаях:
  1. MergeMode=mmNone
  2. заданный диапазон включает только одну ячейку
  3. диапазон задан не с левого верхнего угла
  4. такой диапазон уже есть
  5. заданный диапазон конфликтует с уже имеющимися
function Range(ACol,ARow:integer):TMZRange
– диапазон, содержащий ячейку, nil – в случае отсутствия оного.

procedure SplitAllRanges


function SplitRange(ACol,ARow:integer):boolean


function SplitRange(rng:TMZRange):Boolean
– уничтожение диапазонов

property Ranges[Index:Integer]:TMZRange


property RangeCount:integer
– понятно

property RangeValue[ACol,ARow:integer]:string
– значение диапазона. Если не существует диапазона, включающего данную ячейку, возвращается Cells[ACol, ARow]

property MergeMode:TMergeMode
– понятно

Переписаны методы Paint и DrawCell.

Paint:
  • убрана неиспользуемая теперь переменная LineColor
  • в DrawCells убраны все вызовы DrawFocusRect
  • основном коде метода убран четвертый вызов DrawLines
  • в конце процедуры сами рисуем рамку фокуса DrawFocusRect
Как видите, здесь очень радикальные изменения. ;-)

DrawCell:
Краса и гордость класса. ;-) Метод полностью переписан.
Попробую объяснить, что же я тут наваял.
1) Рисуем границы.
Работаем мы не с фиксированными ячейками. Если ячейка не принадлежит ни одному диапазону – рисуем все ее границы. В противном же случае, внутри диапазона границы стираем, внешние же, напротив, пожирнее.
2) Рисуем содержимое ячейки.
Сначала рассчитываем размер области вывода, затем выводим текст. Все просто.

3. Использование компонента.

При использовании таблицы считаем, что в опциях не установлены флажки goRovMoving, goColMoving, goEditing, goAlwaysShowEditor. Эти ситуации, соответственно, не обрабатываются. Также не используется и InplaceEditor.

4. Недостатки компонента.

  1. Событие OnCellDraw отсутствует. Но нам оно и не было нужно. Хотя… Диапазоны разным цветом можно было бы…
  2. Содержимое диапазона отрисовывается при каждом вызове DrawCell для ячейки диапазона. Т.е. если на экране видно 100 ячеек диапазона, столько и будет и отрисовок. Ну и еще поскроллируйте туда, обратно.…
  3. Нет переноса слов.
  4. Нет выравнивания. Да, это Вам не Ексель.
  5. Когда курсором бегаем по гриду, пересекая объединения, замечаем разрывы на правой и нижней границе.
  6. И самое неприятное. Попробуйте поверх окна с гридом (не важно, в runtime или designtime) повозить другое окно. Или размеры окна примера поизменять. Вот такие вот артефакты. Их появление связано с тем, что, собственно, большого опыта по написанию именно визуальных компонент у меня нет.
5. Пример использования.

Приведенный пример показывает, как осуществляется создание структуры таблицы, и осуществляется ввод текстовых данных.
Скачать архив проекта: MergeGrid.zip (10 K)
6. Совместимость.

Компонент и пример были созданы в D5. Но компилировались и работали также и в D6.

Вот так вот. Надеюсь, эта тема будет интересна не только новичкам, но и продвинутым программистам.

Жду ваших замечаний, советов и пожеланий. Спасибо.

Статья Грид с объединяемыми ячейками данных раздела Компоненты и Классы TStringGrid и TDrawGrid может быть полезна для разработчиков на Delphi и FreePascal.


Комментарии и вопросы


:: 2011-10-21 08:55:22 :: re:Грид с объединяемыми ячейками данных

пользователь: Илья.

Здравствуйте, ссылка уже не рабочая, как можно получить файл проекта?


:: 2011-10-29 19:59:28 :: re:Грид с объединяемыми ячейками данных

пользователь: kan.

К сожалению, архив утерян.


Ваше мнение или вопрос к статье в виде простого текста (Tag <a href=... Disabled). Все комментарии модерируются, модератор оставляет за собой право удалить непонравившейся ему комментарий.

заголовок

e-mail

Ваше имя

Сообщение

Введите код




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: TStringGrid и TDrawGrid ::


реклама



©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru Rambler's Top100
19.04.2024 14:22:56/0.033687829971313/0