C# 最小化功能区时,使功能区上下文AltabGroup显示

C# 最小化功能区时,使功能区上下文AltabGroup显示,c#,wpf,.net-4.0,ribboncontrolslibrary,C#,Wpf,.net 4.0,Ribboncontrolslibrary,以下是场景: 当功能区未最小化时,显示链接到RibbonContextAltabGroup的选项卡可以正常工作,如以下屏幕截图所示 最小化功能区时,显示链接到RibbonContextAltabGroup的选项卡将显示选项卡,但不会显示上下文选项卡组标题,如以下屏幕截图所示 如果功能区最小化,但弹出窗口打开,则显示链接到RibbonContextAltabGroup的选项卡工作正常,如以下屏幕截图所示。(弹出窗口不可见,但这就是我创建场景的方式。) WebMatrix也有这个问题,所以我假

以下是场景:

当功能区未最小化时,显示链接到
RibbonContextAltabGroup
的选项卡可以正常工作,如以下屏幕截图所示

最小化功能区时,显示链接到
RibbonContextAltabGroup
的选项卡将显示选项卡,但不会显示上下文选项卡组标题,如以下屏幕截图所示

如果功能区最小化,但弹出窗口打开,则显示链接到
RibbonContextAltabGroup
的选项卡工作正常,如以下屏幕截图所示。(弹出窗口不可见,但这就是我创建场景的方式。)

WebMatrix也有这个问题,所以我假设Microsoft开发人员有意使用此功能进行编码。但是,在Windows 8/Office 2013中,无论功能区的状态如何,上下文选项卡组始终显示


我使用的是Microsoft的.NET 4.0 RibbonControlsLibrary,因此我可以访问完整的源代码。如何修改代码以强制上下文选项卡组始终显示,而不管功能区的状态如何?

我也遇到了同样的问题,并找到了解决方法

  • 在拥有功能区的窗口中重写OnApplyTemplate方法,以获取RibbonContextAltabGroupItems控件并设置内部字段:

  • 将功能区的IsMinimized属性设置为true,然后将上下文组的可见性设置为visible,然后调用RibbonContextAltabGroupItems控件的UpdateLayout并将功能区的IsMinimized属性重置为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;
        }
    }  
    
    ...  
    
    我还尝试覆盖RibbonContextAltabGroupItemsControl类和Ribbon样式,但没有成功。

    如果还有其他解决方案,我真的很感兴趣。

    在对RibbonControl库的源文件进行了研究,并进行了硬核试验和错误分析之后,我找到了以下解决方案:

    打开位于Microsoft/Windows/Controls/Ribbon的RibbonContextAltabGroupItemsControl.cs,展开Private Methods#区域,找到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;
    }
    
    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;
    }
    
    我只添加了以下两行代码:

    if (Ribbon.IsMinimized)
        return true;
    
    该函数现在应如下所示:

    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;
    }
    
    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;
    }
    
    运行应用程序,voíla,即使功能区最小化,上下文选项卡组现在也会显示


    请注意,如果您没有访问ribbon源代码的权限,那么使用zznobody的解决方案仍然可以在紧要关头工作。

    是的,非常好,非常感谢您,Ming

    是否有一种方法可以使用RibbonContextAltabGroupItemsControl.cs而不复制和重写所有相关的功能区源类

    我再次采用了覆盖ribbon样式的方法来避免这项大量的工作,并最终取得了成功

    有一个触发器用于处理功能区的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控件的内容是一个名为“GroupsOrder”的边框,其中包含所有功能区选项卡。当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>
    
    
    

    请注意,我已将mainItemsPresenterHost控件的Visibility属性的setter替换为Height属性,并将其设置为“0”。

    更新:我添加了一个新答案,效果更好。看看,很好!我不打算在我的应用程序中实现你的解决方案,因为我的应用程序已经在运行了,但如果你无法访问源代码,这看起来是一个很好的解决方案,如.NET4.5的功能区。