RibbonApplicationMenu: getting rid of the AuxiliaryPane

2.7k Views Asked by At

It so happened that the application I'm working on doesn't operate on documents, so there's no need in displaying the recently opened documents list in the application menu.
But - annoyingly - there are no properties readily available in the RibbonApplicationMenu class to hide the unused AuxiliaryPane (for which, curiously, the property does exist, but is marked as "internal").
Of course, I can just leave it there - but that's... untidy.

So, here's the solution I came up with.
Hope it will be helpful for anyone else :-)

The general idea is to subclass the RibbonApplicationMenu, find the template child corresponding to the menu's Popup, and overrule its Width (after a number of frustrating experiments it became evident that doing that neither for PART_AuxiliaryPaneContentPresenter nor for PART_FooterPaneContentPresenter - nor for the both - could achieve anything).

Well, without further ado, here's the code:

public class SlimRibbonApplicationMenu : RibbonApplicationMenu
{
    private const double DefaultPopupWidth = 180;

    public double PopupWidth
    {
        get { return (double)GetValue(PopupWidthProperty); }
        set { SetValue(PopupWidthProperty, value); }
    }

    public static readonly DependencyProperty PopupWidthProperty =
        DependencyProperty.Register("PopupWidth", typeof(double), 
        typeof(SlimRibbonApplicationMenu), new UIPropertyMetadata(DefaultPopupWidth));


    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        this.DropDownOpened += 
            new System.EventHandler(SlimRibbonApplicationMenu_DropDownOpened);
    }

    void SlimRibbonApplicationMenu_DropDownOpened(object sender, System.EventArgs e)
    {
        DependencyObject popupObj = base.GetTemplateChild("PART_Popup");
        Popup popupPanel = (Popup)popupObj;
        popupPanel.Width = (double)GetValue(PopupWidthProperty);
    }
}

As a side note, I tried to find any way to resolve the desired width based on the max width of the ApplicationMenu's Items (rather than setting it explicitly through the DependencyProperty in XAML) - but to no avail.
Given my despise to "magic numbers", any suggestion on that will be deeply appreciated.

2

There are 2 best solutions below

0
On

I know this has been a while, but I've got another solution to this. This one does not provide the Popup width property, instead a ShowAuxilaryPanel boolean. It then goes to Bind the width of the Popup, to the width of the menu item area of the menu.

public class SlimRibbonApplicationMenu : RibbonApplicationMenu
{
    public bool ShowAuxilaryPanel
    {
        get { return (bool)GetValue(ShowAuxilaryPanelProperty); }
        set { SetValue(ShowAuxilaryPanelProperty, value); }
    }

    public static readonly DependencyProperty ShowAuxilaryPanelProperty =
        DependencyProperty.Register("ShowAuxilaryPanel", typeof(bool),
        typeof(SlimRibbonApplicationMenu), new UIPropertyMetadata(true));

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        this.DropDownOpened += SlimRibbonApplicationMenu_DropDownOpened;
    }

    void SlimRibbonApplicationMenu_DropDownOpened(object sender, EventArgs e)
    {
        DependencyObject popupObj = base.GetTemplateChild("PART_Popup");
        Popup panel = (Popup)popupObj;
        var exp = panel.GetBindingExpression(Popup.WidthProperty);

        if (!this.ShowAuxilaryPanel && exp == null)
        {
            DependencyObject panelArea = base.GetTemplateChild("PART_SubMenuScrollViewer");

            var panelBinding = new Binding("ActualWidth")
            {
                Source = panelArea,
                Mode = BindingMode.OneWay
            };
            panel.SetBinding(Popup.WidthProperty, panelBinding);
        }
        else if (this.ShowAuxilaryPanel && exp != null)
        {
            BindingOperations.ClearBinding(panel, Popup.WidthProperty);
        }
    }
}
0
On

worked for me

<telerik:ApplicationMenu RightPaneVisibility="Collapsed" >