Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Hello, World!
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  00:38[Войти] | [Зарегистрироваться]

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

Михаил Зайкин
дата публикации 28-11-2002 12:01

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

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.

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

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

За развитием компонента следите на сайте автора: http://www.mzdelphi.h10.ru/




Смотрите также материалы по темам:
[TStringGrid] [Перерисовка компонент] [Отображение списков, сеток]

 Обсуждение материала [ 29-10-2003 11:37 ] 5 сообщений
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования