WPF Ribbon - 隐藏选项卡标题(单个选项卡应用程序)

9

我是WPF的新手,正在尝试使用Ribbon控件。

我在应用程序中只有一个选项卡,希望隐藏标题但仍然显示选项卡本身。

我尝试了各种属性和样式,但只能隐藏整个选项卡。

我尝试过:ribbontab可见性,ribbontab.header可见性,在TabHeaderItemCollection中设置hidden,将xaml样式应用于ribbontab中的ribbontabheader元素,尝试tabheadertemplate属性,并且通常在API中搜索任何可能相关的内容。

谷歌只提供如何隐藏整个选项卡的方法。

还有其他想法吗?

3个回答

6

我成功地通过将控件向上移动47像素来隐藏选项卡标题和应用程序菜单...

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

注意:您可以通过这样做只隐藏应用程序菜单而不是选项卡...
<r:Ribbon DockPanel.Dock="Top" x:Name="ribbon">             
    <r:Ribbon.ApplicationMenu>
        <r:RibbonApplicationMenu Visibility="Collapsed" />
    </r:Ribbon.ApplicationMenu>

隐藏选项卡标题,我无法完全实现。通过以下覆盖ribbon类,我已经接近完成了...
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);
        }
    }
}

GetDescendants扩展方法只是搜索特定类型的可视树。此方法来自于这里:http://blog.falafel.com/finding-controls-by-type-in-silverlight-and-wpf/
上述方法唯一的问题是好像还剩下一个1像素高的条。你需要仔细观察才能看到它!

感谢flobadob的回答。这个方法也许可行,但是项目现在已经完成了。不幸的是,我不得不模仿一个现有的界面,并最终使用图像和路径来复制功能。这真是一件非常麻烦的事情。 - SeeMoreGain

5
借鉴其他答案的思路,有几种方法可以不使用自定义派生类来完成。
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;

    }
}

然后在您的XAML中:

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

这将为您提供一个漂亮的正方形丝带盒,没有标签:

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

省略折叠行代码会在标签原位置留下一个小凸起,这让我感到不舒服。

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

如果您没有使用MVVM,也可以直接将该装入代码放入代码后面,或者使用EventToCommand。 这种方法不太可重用,但它具有相同的结果。

编辑:这是GetDescendant方法的代码:

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

1
非常感谢这个。在Windows 7和.NET 4.5上运行得很好。 - Rotsiser Mho

0
关于flobadob的回答: 将控件向上移动47像素是一个非常有趣的解决方案。
如果您想保留通常在功能区菜单上方的行,请移动控件,然后在代码中添加一行。以下代码可以实现此目的:
<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" />

将白色填充替换为您背景的颜色。还要注意,缎带是网格行1,而后放置的线是网格行0。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接