Сделать ленту ContextualTabGroups Показать, когда лента свернута
Ниже приведен сценарий:
Когда лента не свернута, отображается вкладка, связанная с RibbonContextualTabGroup
работает нормально, как видно на следующем скриншоте.
Когда лента свернута, отображается вкладка, связанная с RibbonContextualTabGroup
показывает вкладки, но не контекстный заголовок группы вкладок, как видно на следующем снимке экрана.
Если лента свернута, но открыто всплывающее окно с вкладкой, связанной с RibbonContextualTabGroup
работает нормально, как видно на следующем скриншоте. (Всплывающее окно не отображается, но я так и создал сценарий.)
WebMatrix также имеет эту проблему, поэтому я предполагаю, что разработчики Microsoft намеренно закодировали эту функциональность. Однако в Windows 8/Office 2013 контекстные группы вкладок отображаются всегда, независимо от состояния ленты.
Я использую.NET 4.0 RibbonControlsLibrary от Microsoft, поэтому у меня есть доступ к полному исходному коду. Как изменить код так, чтобы контекстные группы вкладок отображались всегда, независимо от состояния ленты?
3 ответа
Да, действительно хорошо, большое спасибо, Мин!
Есть ли способ использовать RibbonContextualTabGroupItemsControl.cs без копирования и переопределения всех связанных классов ленты-источника?
Я снова последовал подходу, переопределяющему стиль ленты, чтобы избежать этой обширной работы, и, наконец, был успешным
Существует триггер, который обрабатывает свойство IsMinimized ленты:
<Trigger Property="IsMinimized" Value="True">
<Setter Property="Content" TargetName="mainItemsPresenterHost" Value="{x:Null}"/>
<Setter Property="Visibility" TargetName="mainItemsPresenterHost" Value="Collapsed"/>
<Setter Property="Content" TargetName="popupItemsPresenterHost" Value="{Binding ElementName=groupsBorder}"/>
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0,0,0,1"/>
</Trigger>
Содержимое mainItemsPresenterHost-control представляет собой границу с именем groupsBorder, которая содержит все вкладки ленты. Когда свойство IsMinimized изменяется на true, эта граница перемещается в презентатор всплывающих окон с именем "popupItemsPresenterHost".
Другой триггер обрабатывает свойство IsDropDownOpen:
<Trigger Property="IsDropDownOpen" Value="True">
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0"/>
/Trigger>
Я изменил оба триггера следующим образом:
<Trigger Property="IsMinimized" Value="True">
<!--<Setter Property="Content" TargetName="mainItemsPresenterHost" Value="{x:Null}"/>-->
<!--<Setter Property="Visibility" TargetName="mainItemsPresenterHost" Value="Collapsed"/>-->
<Setter Property="Height" TargetName="mainItemsPresenterHost" Value="0"/>
<!--<Setter Property="Content" TargetName="popupItemsPresenterHost" Value="{Binding ElementName=groupsBorder}"/>-->
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0,0,0,1"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="True">
<Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0,0,0,1"/>
<Setter Property="Content" TargetName="mainItemsPresenterHost" Value="{x:Null}"/>
<Setter Property="Content" TargetName="popupItemsPresenterHost" Value="{Binding ElementName=groupsBorder}"/>
</Trigger>
Обратите внимание, что я заменил установщик свойства Visibility элемента mainItemsPresenterHost на свойство Height и установил его в "0".
У меня та же проблема, и я нашел этот обходной путь.
Переопределите метод OnApplyTemplate в окне, которому принадлежит лента, чтобы получить RibbonContextualTabGroupItemsControl и установить внутреннее поле:
Установите для свойства IsMinimized ленты значение true, перед тем как установить видимость для контекстной группы видимой, затем вызовите UpdateLayout для RibbonContextualTabGroupItemsControl и сбросьте свойство IsMinimized-Property ленты на false:
Код
...
RibbonContextualTabGroupItemsControl _ribbonContextualTabGroupItemsControl;
...
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Ribbon ribbon = this.ribbon;
ribbon.ApplyTemplate();
this._ribbonContextualTabGroupItemsControl = ribbon.Template.FindName("PART_ContextualTabGroupItemsControl", ribbon) as RibbonContextualTabGroupItemsControl;
}
...
void toggleRibbonContextualGroupVisibility()
{
if(this.ribbonContextualGroup.Visibility == Visibility.Collapsed)
{
if (this.ribbon.IsMinimized)
{
this.ribbon.IsMinimized = false;
this.ribbonContextualGroup.Visibility = Visibility.Visible;
this._ribbonContextualTabGroupItemsControl.UpdateLayout();
this.ribbon.IsMinimized = true;
}
else
{
this.ribbonContextualGroup.Visibility = Visibility.Visible;
}
}
else
{
this.ribbonContextualGroup.Visibility = Visibility.Collapsed;
}
}
...
Я также попытался переопределить RibbonContextualTabGroupItemsControl-class и Ribbon-style безуспешно.
Если есть какие-то другие решения, мне действительно интересно.
После игры с исходными файлами для RibbonControlsLibrary и просто пробного использования метода проб и ошибок я нашел следующее решение:
Откройте RibbonContextualTabGroupItemsControl.cs, расположенный по адресу Microsoft/Windows/Controls/Ribbon, разверните раздел Private Methods #region и найдите функцию HasTabs. Код должен выглядеть примерно так:
private bool HasTabs(FrameworkElement container)
{
RibbonContextualTabGroup tabGroupHeader = container as RibbonContextualTabGroup;
if (tabGroupHeader == null ||
!tabGroupHeader.IsVisible)
{
return false;
}
foreach (RibbonTab tab in tabGroupHeader.Tabs)
{
if (tab != null && tab.IsVisible)
{
return true;
}
}
return false;
}
Все, что я добавил, это следующие две строки кода:
if (Ribbon.IsMinimized)
return true;
Теперь функция должна выглядеть так:
private bool HasTabs(FrameworkElement container)
{
RibbonContextualTabGroup tabGroupHeader = container as RibbonContextualTabGroup;
if (tabGroupHeader == null ||
!tabGroupHeader.IsVisible)
{
return false;
}
if (Ribbon.IsMinimized)
return true;
foreach (RibbonTab tab in tabGroupHeader.Tabs)
{
if (tab != null && tab.IsVisible)
{
return true;
}
}
return false;
}
Запустите ваше приложение и, наконец, контекстные группы вкладок теперь отображаются, даже если лента свернута.
Обратите внимание, что если у вас нет доступа к исходному коду ленты, использование решения zznobody все равно будет работать на пределе.