8
votes

I am new to WPF and am trying to use the Ribbon control.

I have a single tab in the application, and wish to hide the header but still show the tab itself.

I have been experimenting with various properties and styles, but I have only been able to hide the entire tab.

I've tried: ribbontab visibility, ribbontab.header visibility, setting hidden in TabHeaderItemCollection, applying style xaml to ribbontabheader element in ribbontab, experimenting with tabheadertemplate property, and generally sifting through the api looking for anything that may be relevant.

Google only turns up how to hide the whole tab.

Any other ideas?

3

3 Answers

5
votes

I managed to hide both the tab headers and the application menu by shifting the control 47 pixels upwards...

<r:Ribbon Margin="0,-47,0,0" DockPanel.Dock="Top" x:Name="ribbon">

Note: you can hide just the application menu and not the tabs by doing this...

<r:Ribbon DockPanel.Dock="Top" x:Name="ribbon">             
    <r:Ribbon.ApplicationMenu>
        <r:RibbonApplicationMenu Visibility="Collapsed" />
    </r:Ribbon.ApplicationMenu>

Hiding just the tab headers, I can't quite do. I did get pretty close by overriding the ribbon class as follows...

class RibbonNoTab : Ribbon
{
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        var ctrl = this.GetDescendants<Grid>().FirstOrDefault();
        if (ctrl != null)
        {
            ctrl.RowDefinitions[1].Height = new GridLength(0, System.Windows.GridUnitType.Pixel);
        }
    }
}

The GetDescendants extension method just searches the visual tree for something of a specified type. It was taken from here: http://blog.falafel.com/finding-controls-by-type-in-silverlight-and-wpf/

The only issue with the above method was that there looks like a 1 pixel high bar remaining. You have to look pretty closely to see it!

4
votes

Piggybacking off the other answer, there are a few ways you can do it without using a custom derived class

public class RibbonBehavior
{

    public static bool GetHideRibbonTabs(DependencyObject obj)
    {
        return (bool)obj.GetValue(HideRibbonTabsProperty);
    }

    public static void SetHideRibbonTabs(DependencyObject obj, bool value)
    {
        obj.SetValue(HideRibbonTabsProperty, value);
    }

    // Using a DependencyProperty as the backing store for HideRibbonTabs.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HideRibbonTabsProperty =
        DependencyProperty.RegisterAttached("HideRibbonTabs", typeof(bool), typeof(RibbonBehavior), new UIPropertyMetadata(false,OnHideRibbonTabsChanged));



    public static void OnHideRibbonTabsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d == null || d.GetType() != typeof(Ribbon)) return;

        (d as Ribbon).Loaded += ctrl_Loaded;

    }

    static void ctrl_Loaded(object sender, RoutedEventArgs e)
    {
        if (sender == null || sender.GetType() != typeof(Ribbon)) return;

        Ribbon _ribbon = (Ribbon)sender;

        var tabGrid = _ribbon.GetDescendants<Grid>().FirstOrDefault();
        tabGrid.RowDefinitions[1].Height = new GridLength(0, System.Windows.GridUnitType.Pixel);


        foreach (Line line in _ribbon.GetDescendants<Line>())
            line.Visibility = Visibility.Collapsed;

    }
}

then in your xaml:

<Ribbon SelectedIndex="0" a:RibbonBehavior.HideRibbonTabs="true">

Which will give you a nice square ribbon box with no tab:

http://i.imgur.com/yCtt441.png

Leaving out the code collapsing the lines leaves a little blip where the tab used to be, which was bothering me.

http://i.imgur.com/eDQ8yVw.png

You could also put that loaded code straight into the code behind if you're not using MVVM, or in an EventToCommand if you are. This way is less reusable, but it's the same results.

EDIT: Here's the code for the GetDescendant methods

 public static class VisualTreeExtensions
{
    /// <summary>
    /// Gets children, children’s children, etc. from 
    /// the visual tree that match the specified type
    /// </summary>
    public static List<T> GetDescendants<T>(this DependencyObject parent)
        where T : UIElement
    {
        List<T> children = new List<T>();
        int count = VisualTreeHelper.GetChildrenCount(parent);
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
                if (child is T)
                {
                    children.Add((T)child);
                }
                children.AddRange(child.GetDescendants<T>());
            }
            return children;
        }
        else
        {
            return new List<T> { };
        }
    }
    /// <summary>
    /// Gets children, children’s children, etc. from 
    /// the visual tree that match the specified type and elementName
    /// </summary>
    public static List<T> GetDescendants<T>(this DependencyObject parent, string elementName)
        where T : UIElement
    {
        List<T> children = new List<T>();
        int count = VisualTreeHelper.GetChildrenCount(parent);
        if (count > 0)
        {
            for (int i = 0; i < count; i++)
            {
                UIElement child = (UIElement)VisualTreeHelper.GetChild(parent, i);
                if (child is T && (child is FrameworkElement)
                    && (child as FrameworkElement).Name == elementName)
                {
                    children.Add((T)child);
                }
                children.AddRange(child.GetDescendants<T>(elementName));
            }
            return children;
        }
        else
        {
            return new List<T> { };
        }
    }
    /// <summary>
    /// Gets the first child, child’s child, etc. 
    /// from the visual tree that matches the specified type
    /// </summary>
    public static T GetDescendant<T>(this DependencyObject parent)
        where T : UIElement
    {
        List<T> descendants = parent.GetDescendants<T>();
        if (descendants.Count > 0)
        {
            return descendants[0];
        }
        else
        {
            return null;
        }
    }
    /// <summary>
    /// Gets the first child, child’s child, etc. from 
    /// the visual tree that matches the specified type and elementName
    /// </summary>
    public static T GetDescendant<T>(this DependencyObject parent, string elementName)
        where T : UIElement
    {
        List<T> descendants = parent.GetDescendants<T>(elementName);
        if (descendants.Count > 0)
        {
            return descendants[0];
        }
        else
        {
            return null;
        }
    }
    /// <summary>
    /// Gets the first parent, parent’s parent, etc. from the 
    /// visual tree that matches the specified type
    /// </summary>
    public static T GetAntecedent<T>(this DependencyObject root)
        where T : UIElement
    {
        if (root == null)
        {
            return null;
        }
        if (root is T)
        {
            return (T)root;
        }
        else
        {
            DependencyObject parent = VisualTreeHelper.GetParent(root);
            if (parent == null)
            {
                return null;
            }
            else
            {
                return parent.GetAntecedent<T>();
            }
        }
    }
    /// <summary>
    /// Gets the first parent, parent’s parent, etc. from the 
    /// visual tree that matches the specified type and elementName
    /// </summary>
    public static T GetAntecedent<T>(this DependencyObject root, string elementName)
        where T : UIElement
    {
        if (root == null)
        {
            return null;
        }
        if (root is T && (root is FrameworkElement)
            && (root as FrameworkElement).Name == elementName)
        {
            return (T)root;
        }
        else
        {
            DependencyObject parent = VisualTreeHelper.GetParent(root);
            if (parent == null)
            {
                return null;
            }
            else
            {
                return parent.GetAntecedent<T>(elementName);
            }
        }
    }
}
0
votes

In relation to flobadob's answer: Shifting the control up 47 pixels is quite an interesting solution.

If you want to retain the line that is normally above the ribbon menu, shift the control, and then add a line in code. The following will work:

<ribbon:XamRibbon Grid.Row="1" x:Name="Ribbon" ApplicationMenuMode="Office2010" AllowMinimize="False" Margin="0,-49,0,0">
...
</ribbon:XamRibbon>

<Rectangle Grid.Row="0" HorizontalAlignment="Stretch" Fill="White" Height="5"/>
<Separator Grid.Row="0" />

Replace the white fill with the color of your background. Note also that the ribbon is Grid row 1, whereas the later placed line is grid row 0.