Cepгей Poщин дата публикации 03-10-2006 08:05 Пример работы Docking-технологии
Предлагаю к обсуждению реализацию фрейма, позволяющего упростить использование технологии Docking (Drag-and-Dock).
В начале работы программы все органы управления со свойством DragKind=dkDock, лежащие на TFrameSite, автоматически пристыковываются (см. CreateHandle).
Если рядом с фреймом располагается TSplitter, то он будет также скрываться и отображаться. Рекомендую установить свойство TSplitter.AutoSnap=False.
Поскольку у фрейма установлено свойство UseDockManager=true, то для управления координатами, и изображения областей перетаскивания пристыкованных объектов создается специальный объект DockManager, по умолчанию он является экземпляром класса TDockTree. Добавлен его потомок TDockTreeCep изображающий названия пристыкованных объектов и более правильно загружающий свое состояние (в BDS2005 появился также класс TCaptionedDockTree).
Для записи и чтения состояния фрейма из потока добавлены методы:
procedure SaveToStream(Stream: TStream);
procedure LoadFromStream(Stream: TStream);
Стандартно, при чтении/записи координат пристыкованных объектов поиск осуществляется по имени компонента, и только на владельце (см. TWinControl.ReloadDockedControl). В TFrameSite поиск осуществляется рекурсивно в пределах всего приложения, что расширяет возможности применения Drag-and-Dock, но требует, что бы все пристыковываемые контролы имели уникальное имя!
Для управления внешним видом и поведением стыковки добавлено свойство
property DockTreeKind: TDockTreeKind;
TDockTreeKind = (dtkDefaul, dtkCep, dtkOld);
- dtkDefaul — для отображения пристыкованных и отстыкованных объектов используются экземпляры классов определенных переменными DefaultDockTreeClass и DefaultDockFormClass;
- dtkCep — для отображения пристыкованных и отстыкованных объектов используются экземпляры классов TDockTreeCep и TCustomDockFormCep соответственно;
- dtkOld — для отображения пристыкованных и отстыкованных объектов используются экземпляры классов TDockTree и TCustomDockForm соответственно (стандартный для Delphi вариант).
Когда контрол бросается в свободную область экрана он помещается в форму-носитель TCustomDockForm. Для исправления проблем, связанных с неправильными координатами и положением формы добавлен класс TCustomDockFormEx. Кроме того в него добавлено свойство TimerVisible выполняющее отложенное изменение свойства Visible.
Для отображения «плоских» форм добавлен класс TCustomDockFormCep.
Сохранение/восстановление координат форм-носителей производится с помощью класса TFloatTreeCep и должно выполняться в первую очередь.
FloatTreeCep.LoadFromStream(Stream);
FrameSite1.LoadFromStream(Stream);
FrameSite2.LoadFromStream(Stream);
Отображением контрола во время перетаскивания занимается экземпляр класса TDragDockObject, который может быть создан в обработчике события OnStartDock. Добавлен его потомок TDragDockObjectCep, меняющий поведение панелей при перетаскивании.
Добиться полностью удовлетворяющей меня работы не удалось, например, после загрузки фрейма со скрытыми контролами его поведение не всегда адекватно (см. контекстное меню). В Delphi5 иногда появляется ошибка деления на ноль.
P. S. Не будьте строги к содержанию статьи (я не писатель), лучше смотрите исходники и пример, которые проверялись в Delphi 5 и BDS 2006.
К материалу прилагаются файлы:
[Drag&Drop] [Docking]
Обсуждение материала [ 27-01-2010 03:00 ] 3 сообщения |