When working
with Embarcadero TRibbon component, usually we need to make several changes in
the ribbon items including removing a ribbon page, making invisible the ribbon
groups and items, and repositioning still visible ribbon groups.
Unfortunately,
I couldn’t find straightforward methods in the Embarcadero’s TRibbon component
to make these tasks easy to do (I am using C++Builder XE2 Update 3). So, I
wrote some methods to solve them:
In this
article, I supposed that you have an instance of TRibbon (named Ribbon1) on the
current form (Form1) and all of the below methods are members of the form.
To remove a ribbon
page (tab) from the ribbon, you can simply use the RemoveTab method of TRibbon
class; but if you try to remove a page which has one or more ribbon groups, you
will get unexpected access violation error messages. So you need to remove all
of the groups in the page before removing the page:
void
__fastcall TForm1::RemoveRibbonPage(TRibbonPage *Page)
{
for(int i = Page->GroupCount
- 1; i >= 0; i--)
RemoveGroupItems(Page,
(TRibbonGroup *)Page->Groups[i], false, true);
Ribbon1->RemoveTab(Page->Caption);
}
//---------------------------------------------------------------------------
To remove ribbon
group items, use the following method:
void
__fastcall TForm1::RemoveGroupItems(TRibbonPage *Page, TRibbonGroup *Group,
bool KeepVisible, bool RemoveIfEmpty)
{
for(int j =
Group->Items->Count - 1; j >= 0; j--)
{
if(!KeepVisible
|| !Group->Items->ActionClients[j]->Visible ||
(Group->Items->ActionClients[j]->Separator
&& (j == Group->Items->Count - 1 || !j)))
Group->Items->Delete(j);
}
RemoveExtraSeparators(Page, Group);
if(RemoveIfEmpty &&
Group->Items->Count == 0)
Page->RemoveControl(Group);
}
//---------------------------------------------------------------------------
The
KeepVisible parameter indicates whether all of the group items should be
removed, or just non-visible ones.
The RemoveIfEmpty
parameter indicates whether to remove the ribbon group if there is no item
available
When you
delete only non-visible group items, some separator items may be still
available as the first or last items of the group. They will be removed by
calling the below method:
void
__fastcall TForm1::RemoveExtraSeparators(TRibbonPage *Page, TRibbonGroup
*Group)
{
for(int j =
Group->Items->Count - 1; j >= 0; j--)
{
if(Group->Items->ActionClients[j]->Separator
&&
(j == Group->Items->Count - 1 || !j))
Group->Items->Delete(j);
}
}
//---------------------------------------------------------------------------
When removing
ribbon groups from a page, you may noticed that the width of the ribbon groups which
have non-visible items will not be decreased, and you will see some empty
spaces in the group. You need to permanently delete the group item from the
memory. The below method, scans all of the pages, and removes all of the non-visible
group items. By calling this method, extra group spaces will be collapsed.
void
__fastcall TForm1::RemoveNonVisibleRibbonItems(void)
{
TRibbonPage *Page;
for(int i = 0; i <
Ribbon1->Tabs->Count; ++i)
{
Page =
(TRibbonPage *)Ribbon1->Tabs->Items[i]->Page;
for(int j =
Page->GroupCount - 1; j >= 0; j--)
RemoveGroupItems(Page,
(TRibbonGroup *)Page->Groups[j], true, true);
}
}
//---------------------------------------------------------------------------
When you
remove a group from a page, the group will be removed from the memory (I
guess), but the basic information of the group will be kept in the page’s
Groups list, so you will see empty spaces at the position of the removed ribbon
groups. To correct this problem, simply change the index of the removed (non-visible)
groups to put them at the end of the Groups items. This way, all of the groups
will be arranged completely:
void
__fastcall TForm1::MoveNonVisibleRibbonGroups(void)
{
TRibbonPage *Page;
int Index;
int Counter;
for(int i = 0; i < Ribbon1->Tabs->Count;
++i)
{
Page =
(TRibbonPage *)Ribbon1->Tabs->Items[i]->Page;
Index =
FindMaxRibbonGroupIndex(Page) + 1;
for(int j = 0; j
< Page->GroupCount; ++j)
{
Counter
= j;
while(!Page->Groups[j]->Visible
&& Counter++ < Page->GroupCount)
Page->Groups[j]->GroupIndex
= ++Index;
}
}
}
//---------------------------------------------------------------------------
To set a
group as the last item, of the ribbon page’s Groups list, you need to find the
last index number used by the groups. Use FindMaxRibbonGroupIndex method to get
the last index:
int
__fastcall TForm1::FindMaxRibbonGroupIndex(TRibbonPage *Page)
{
int ReturnValue = -1;
for(int j = Page->GroupCount
- 1; j >= 0; j--)
ReturnValue =
MAX(ReturnValue, Page->Groups[j]->GroupIndex);
return ReturnValue;
}
//---------------------------------------------------------------------------
As a recommendation,
you set the visibility of the group items you want to keep them on the ribbon, and
call the below commands to arrange all of the remaining groups and group items
completely:
RemoveNonVisibleRibbonItems();
MoveNonVisibleRibbonGroups();
Any comments
on this article would be highly welcomed.
is it possible remove a button/action from group?
ReplyDelete