سؤال

The following is the scenario:

When the ribbon is not minimized, showing a tab linked to a RibbonContextualTabGroup works fine, as visible in the following screenshot.

Normal Ribbon

When the ribbon is minimized, showing a tab linked to a RibbonContextualTabGroup shows the tabs, but not the contextual tab group header, as visible in the following screenshot.

Minimized Ribbon

If the ribbon is minimized, but the popup is open, showing a tab linked to a RibbonContextualTabGroup works fine, as visible in the following screenshot. (The popup is not visible, but that is how I created the scenario.)

Minimized Ribbon w/Open Popup

WebMatrix also has this problem, so I am assuming that Microsoft developers intentionally coded in this functionality. In Windows 8/Office 2013, however, the contextual tab groups always show, regardless of the state of the ribbon.

I am using the .NET 4.0 RibbonControlsLibrary from Microsoft, so I have access to the full source code. How can I modify the code to force the contextual tab groups to always show, regardless of the state of the ribbon?

هل كانت مفيدة؟

المحلول

Yes, really good, thank you very much, Ming!

Is there a way to use RibbonContextualTabGroupItemsControl.cs without copying and overriding all relating ribbon-source-classes?

I followed again the approach overriding the ribbon style to avoid this extensive work and was finally successful

There is a trigger that handles the IsMinimized-property of the ribbon:

<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>

The content of mainItemsPresenterHost-control is a border named 'groupsBorder' that contains all ribbon tabs. When the IsMinimized-property changes to true, this border is moved to the popup presenter named 'popupItemsPresenterHost'.

An other trigger handles the IsDropDownOpen-property:

<Trigger Property="IsDropDownOpen" Value="True">
    <Setter Property="BorderThickness" TargetName="BackgroundBorder" Value="0"/>
/Trigger>

I changed both trigger as follows:

<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>

Note that i have replaced the setter of the Visibility-property of the mainItemsPresenterHost-control with the Height-property and set it to '0'.

نصائح أخرى

i have the same problem and have found this workaround.

  1. Override the OnApplyTemplate-method in the window that owns the ribbon to get the RibbonContextualTabGroupItemsControl and set internal field:

  2. Set the IsMinimized-property of the ribbon to true, before setting the visibility to the contextual group to visible, then call UpdateLayout of the RibbonContextualTabGroupItemsControl and reset the IsMinimized-Property of the ribbon to false:

Code

...
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;
    }
}  

...  

I also have tried to override the RibbonContextualTabGroupItemsControl-class and the Ribbon-style without success.
If there are any other solutions, i am really interested in.

After playing around with the source files for the RibbonControlsLibrary, and just doing hardcore trial-and-error, I found the following solution:

Open RibbonContextualTabGroupItemsControl.cs, located at Microsoft/Windows/Controls/Ribbon, expand the Private Methods #region, and locate the HasTabs function. The code should look something like this:

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;
}

All I added was the following two lines of code:

if (Ribbon.IsMinimized)
    return true;

The function should now look like this:

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;
}

Run your application, and voíla, the contextual tab groups now show even if the ribbon is minimized.

Note that if you do NOT have access to the ribbon source code, then using zznobody's solution will still work at a pinch.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top