уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Как Вы, наверное, знаете из комментариев в блоге сейчас я работаю над объединением всех статей про Ribbon Controls в Delphi в один большой документ. Что получится в итоге — пока не известно даже мне. Может это будет простой пост на 7000+ слов с картинками, а может и целый справочник для начинающих программистов. Пока кодовое название документа «Ribbon Controls. Мышинное программирование«. Может звучит немного странно, но вполне отражает суть того, что пока изложено. Дело в том, что большинство действий, совершаемых при работе с Ribbon — это движения мышкой по экрану. Эдакое программирование для дошкольников — взял кнопочку, перетянул на панельку, выбрал мышкой в свойствах значение, ткнул мышкой 2 раза, написал 1 строчку и всё готово. Только вот, как показывают вопросы по Ribbon от читателей блога, да и собственный хоть и не большой, но опыт — иногда бывает очень не просто ухватить мышкой тот самый элемент :) Понимаю, что может звучит и немного неправдоподобно, но так и есть. Часто приходится выделывать что-то наподобие тануа с бубном, чтобы сделать запланированной. Вот я и решил, что хватит уже мучится с мышкой, пора бы перейти к более серьезной работе. А именно — работать с Ribbon Controls именно как с объектами Delphi, без всяких тасканий и перетаскиваний — только код.

Однако, перед тем как перейдем к практической реализации заявленной темы, хочу Вам сообщить одно пренеприятнейшее известие. К нам едет ревизор. В блоге теперь работает защита от копирования контента. Может это и не 100% защита, но всяким нечистоплотным копипастерам, боящимся поставить обратную ссылку на первоисточник, кровь немного попортит.

Ну, а мы пока перейдем к нашим Ribbon Controls в Delphi. Сегодня рассмотрим небольшой пример создания панелей и групп Ribbon в real-time.


Как Вы уже знаете, в основе Ribbon лежат три вида компонентов: вкладка, группа и элемент, отвечающий за выполнение какого-либо действия (Кнопки, ComboBox  и т.д.). При этом элементы располагаются в группах, а те, в свою очередь на вкладках и умещается всё это хозяйство на родительском компоненте TRibbon.

Собственно, имея в руках только эту информацию, уже можно определиться с созданием вкладок и групп на Ribbon. Поэтому сразу и приступим к программированию.

Открываем Delphi, создаем новое приложение и укладываем на форму стандартный для Ribbon набор компонентов: ActionManager, ImageList и TRibbon. Создавать все элементы интерфейса будем по клику на кнопке TButton. Вид нашего будущего приложения должен быть примерно таким:

Первое, что нам необходимо — это создать новую вкладку. Вся совокупность вкладок (Tabs) является коллекцией TRibbonTabs, которая имеет следующее описание:

TRibbonTabs = class(TOwnedCollection)
private
  FDesignerAdd: Boolean;
  function GetItem(Index: Integer): TRibbonTabItem;
  procedure SetItem(Index: Integer; const Value: TRibbonTabItem);
  function GetRibbon: TCustomRibbon;
  procedure CreatePageForItem(AItem: TRibbonTabItem);
protected
  procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override;
public
  constructor Create(AOwner: TPersistent; ItemClass: TCollectionItemClass);
  function Add: TRibbonTabItem;
  function FindGroup(const GroupName: string): TControl;
  function GetPageFromPageCaption(const Caption: string): TCustomRibbonPage;
  function IndexOfCaption(const Caption: string): Integer;
  function TabExists(const Caption: string): Boolean;
  function SelectNext: Boolean;
  function SelectPrior: Boolean;
  property DesignerAdd: Boolean read FDesignerAdd write FDesignerAdd;
  property Ribbon: TCustomRibbon read GetRibbon;
  property Items[Index: Integer]: TRibbonTabItem read GetItem write SetItem; default;
end;

Как можно видеть из приведенного листинга, отдельная вкладка — это объект TRibbonTabItem. Попробуем создать новую вкладку. Создаем событие onClick  у Button1 и пишем :

procedure TForm5.Button1Click(Sender: TObject);
var RibbonTabItem:TRibbonTabItem;
begin
  RibbonTabItem:=TRibbonTabItem.Create(ribbon1.Tabs);
end;

Теперь можете запустить приложение и убедиться, что новая вкладка создается и содержит стандартное название типа «RibbonTab1», «RibbonTab2» и т.д. Но нам-то необходимо нормальное название. Поэтому давайте немного разберемся с объектом TRibbonTabItem.

В числе прочих, TRibbonTabItem имеет следующие свойства:

BestTabWidth: Integer — оптимальная ширина вкладки, т.е. ширина вкладки не может быть больше этого значения. Свойство только для чтения.
MinTabwidth: Integer — минимальная ширина вкладки . Свойство только для чтения
Caption: string — заголовок вкладки.
Page: TCustomRibbonPage — объект, содержащий все необходимые свойства и методы для управления дочерними элементами вкладки (группами).

Таким образом, нам пригодятся сегодня два свойства: Caption и Page. Вначале изменим заголовок новой вкладки, например, воспользовавшись свойством Count у колеекции Ribbon1.Tabs :

[...]
  RibbonTabItem.Caption:='Tab #'+IntToStr(Ribbon1.Tabs.Count);
[...]

В итоге при работе с приложением у Вас должно получиться примерно следующее:

Двигаемся дальше. Следующий шаг — добавление ной группы. Здесь в принципе тоже нет никаких сложностей — каждая группа — это дочерний элемент вкладки. Здесь при работе, нам как раз и пригодиться свойство Page: TCustomRibbonPage.

Объект TCustomRibbonPage содержит следующие полезные для нас публичные свойства и методы:

procedure AlignGroups — автоматическое выравнивание групп на вкладке
procedure AddGroup(const Group: TCustomRibbonGroup) — добавление новой группы на вкладку
function FindGroup(const GroupCaption: string): TControl — поиск группы по её заголовку
function FindGroupAt(const Pt: TPoint): TCustomRibbonGroup — поиск группы по координатам точки.
property GroupCount: Integer — количество групп на вкладке
property Groups[Index: Integer]: TCustomRibbonGroup — отдельная группа вкладки
property Index: Integer — порядковый номер вкладки на Ribbon
property Ribbon: TCustomRibbon — родительский элемент вкладки.

Для того, чтобы добавить новую группу нам необходимо воспользоваться методом AddGroup где в качестве входного параметра выступает добавляемая нами группа. Что ж, приступим. Добавляем новую переменную типа TCustomRibbonGroup в обработчик события и пишем:

[...]
  Group:=TRibbonGroup.Create(RibbonTabItem.page);//группа размещается на вкладке
  RibbonTabItem.Page.AddGroup(Group); //добавляем группу в коллекцию
  Group.Parent:=RibbonTabItem.Page; //указываем родительский элемент для группы
  Group.Caption:='Group #'+IntToStr(RibbonTabItem.Page.GroupCount);//указываем заголовок
[...]

Теперь при каждом клике по кнопке в real-time создается новая вкладка и на каждой вкладке одна группа.  Следует отметить, что каждая новая группа по умолчанию имеет следующие свойства:

Width := 200;
  Height := TCustomRibbon.cRibbonGroupHeight;//86 px
  Align := alNone;
  GroupAlign := gaVertical;
  Rows := 3; //количество строк

В принципе, вы всегда можете изменить некоторые из этих свойств как Вам угодно.

Теперь остался один открытый вопрос: зачем нам на форме два лишних компонента — ActionManager и ImageList?

Ответ на этот вопрос, Вы узнаете в следующем посте. Будем работать непосредственно с отдельными группами, элементами и  действиями. А пока можете сохранить приложение, т.к. оно нам ещё пригодиться, подписаться на RSS и ждать новых публикаций в блоге webdelphi.ru :)

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
12 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Жека
Жека
22/06/2010 21:04

Не подскажите как сделать так что б по нажатию на кнопку открывалась нужная вкладка (например на Вкладке1 существует кнопку(Action1), после её нажатия должна открыться Вкладка2… как это сделать?)

Жека
Жека
23/06/2010 00:13

так вот в этом и вопрос… как правильно написать что б работало.. а то всё никак не получается (((

Жека
Жека
23/06/2010 00:55

Ribbon1.ActivePage.Index:=2
или
Ribbon1.ActivePage := — этот вариант Делфи не принимает
или
RibbonPage2.Show; и все без результата

Жека
Жека
24/06/2010 17:28

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

bambarmia
bambarmia
10/07/2010 08:49

Спасибо, Vlad, статья, как всегда, на высоте. Отлично дополняет пример http://www.webdelphi.ru/2009/10/ribbon-controls-shag-za-shagom-shag-1-vizualnaya-razrabotka-interfejsa/#comment-1780 ! // Только не сочтите за занудство, но, коли планируете издать «справочник», перефразируйте «Часто приходится выделывать что-то наподобие тануа с бубном, чтобы сделать запланированной.»
С уважением, благодарный читатель)))

ppush
ppush
08/11/2010 18:34

Спасибо, Vlad, статья отличная.
Но у меня возникла тпкая проблема ,
При создании вкладок в цикле например что-то такое
[code]
Ribbon1.BeginUpdate;
for j := 0 to 20 do
begin
I_Loop := Length(RibonPages);
SetLength(RibonPages, I_Loop + 1);
RibonPages[I_Loop] := TRibbonPage.Create(Self);
RibonPages[I_Loop].Name := 'RP_SYSDBA'+IntToStr(j);
RibonPages[I_Loop].Parent := Ribbon1;

RibonPages[I_Loop].Caption :=GetString('SYSDBA');
Ribbon1.AddTab(RibonPages[I_Loop]);
end;

Ribbon1.EndUpdate;

[/code]

перерисовка  Ribbon-а при каждой интерации создает довольнотаки неприятное впечатление
и кажется Ribbon1.BeginUpdate не работает.

Если сталкивались с подобным пожалусто напишите как с этом справиться.

Drump
Drump
26/08/2011 12:12

Недавно столкнулся с такой проблемой: при разработке необходимо создавать вкладку(и группы в ней) динамически. Но при создании RibbonGroup цвет Caption не черный, а какой-то розоватый. На другом компьютере — голубой. Но самое интересное то, что вторая вкладка создается с нормальным цветом! Не подскажите в чем дело? И как сделать чтобы цвет был «нормальным».