如何在RibbonApplicationMenu的头部设置文本

Bri*_*ett 23 wpf ribbon ribbon-control ribboncontrolslibrary

我正在尝试将文本放在RibbonApplicationMenu的顶层(尝试获取类似于Word或Outlook的"文件"一词).似乎Microsoft.Windows.Controls.Ribbon.RibbonApplicationMenu http://msdn.microsoft.com/en-us/library/microsoft.windows.controls.ribbon.ribbonapplicationmenu.aspx支持SmallImageSource但没有文本属性.设置该Label属性不适用于此问题.

xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"    
<ribbon:RibbonApplicationMenu Label="File"> <!--doesn't set the label -->

</ribbon:RibbonApplicationMenu>
Run Code Online (Sandbox Code Playgroud)

目标是在下面的圆圈区域中显示"文件"一词.

RibbonApplicationMenu

Bri*_*ett 21

最简单的解决方案(我)是插入DrawingImageGlyphRun内.在一篇文章中询问如何获取GlyphRun的AdvanceWidths和GlyphIndicies.结果如下

<ribbon:RibbonApplicationMenu.SmallImageSource>
    <DrawingImage>
        <DrawingImage.Drawing>
            <GlyphRunDrawing ForegroundBrush="White">
                <GlyphRunDrawing.GlyphRun>
                    <GlyphRun
                            CaretStops="{x:Null}" 
                            ClusterMap="{x:Null}" 
                            IsSideways="False" 
                            GlyphOffsets="{x:Null}" 
                            GlyphIndices="41 76 79 72" 
                            FontRenderingEmSize="12" 
                            DeviceFontName="{x:Null}" 
                            AdvanceWidths="5.859375 2.90625 2.90625 6.275390625">
                        <GlyphRun.GlyphTypeface>
                            <GlyphTypeface FontUri="C:\WINDOWS\Fonts\SEGOEUI.TTF"/>
                        </GlyphRun.GlyphTypeface>
                    </GlyphRun>
                </GlyphRunDrawing.GlyphRun>
            </GlyphRunDrawing>
        </DrawingImage.Drawing>
    </DrawingImage>
</ribbon:RibbonApplicationMenu.SmallImageSource>
Run Code Online (Sandbox Code Playgroud)

结果功能区:

GlyphRun结果

  • @ 00jt +1.我不敢相信我必须把这个肮脏的东西放到一个如此简单的工作上(我不是说答案不好.我实际上认为它很棒而且很复杂,只是微软真的在这里吹了它). (7认同)
  • 这显然是需要修复的东西......它应该只是:Label ="File" (6认同)

Edw*_*rey 13

删除可视树的不需要的元素,并用TextBlock替换它们,TextBlock从Label属性中获取文本.您必须为主视觉树上的按钮和弹出窗口的可视树执行此操作.最后,由于文本比典型图像更复杂,因此退回航空突出显示效果会很有帮助.

要使用以下代码,请为XAML中的应用程序菜单指定一个名称,并ReplaceRibbonApplicationMenuButtonContent从窗口的Loaded事件处理程序中调用它.

/// <summary>
/// Replaces the image and down arrow of a Ribbon Application Menu Button with the button's Label text.
/// </summary>
/// <param name="menu">The menu whose application button should show the label text.</param>
/// <remarks>
/// The method assumes the specific visual tree implementation of the October 2010 version of <see cref="RibbonApplicationMenu"/>.
/// Fortunately, since the application menu is high profile, breakage due to version changes should be obvious.
/// Hopefully, native support for text will be added before the implementation breaks.
/// </remarks>
void ReplaceRibbonApplicationMenuButtonContent(RibbonApplicationMenu menu)
{
    Grid outerGrid = (Grid)VisualTreeHelper.GetChild(menu, 0);
    RibbonToggleButton toggleButton = (RibbonToggleButton)outerGrid.Children[0];
    ReplaceRibbonToggleButtonContent(toggleButton, menu.Label);

    Popup popup = (Popup)outerGrid.Children[2];
    EventHandler popupOpenedHandler = null;
    popupOpenedHandler = new EventHandler(delegate
    {
        Decorator decorator = (Decorator)popup.Child;
        Grid popupGrid = (Grid)decorator.Child;
        Canvas canvas = (Canvas)popupGrid.Children[1];
        RibbonToggleButton popupToggleButton = (RibbonToggleButton)canvas.Children[0];
        ReplaceRibbonToggleButtonContent(popupToggleButton, menu.Label);
        popup.Opened -= popupOpenedHandler;
    });
    popup.Opened += popupOpenedHandler;
}

void ReplaceRibbonToggleButtonContent(RibbonToggleButton toggleButton, string text)
{
    // Subdues the aero highlighting to that the text has better contrast.
    Grid grid = (Grid)VisualTreeHelper.GetChild(toggleButton, 0);
    Border middleBorder = (Border)grid.Children[1];
    middleBorder.Opacity = .5;

    // Replaces the images with the label text.
    StackPanel stackPanel = (StackPanel)grid.Children[2];
    UIElementCollection children = stackPanel.Children;
    children.RemoveRange(0, children.Count);
    TextBlock textBlock = new TextBlock(new Run(text));
    textBlock.Foreground = Brushes.White;
    children.Add(textBlock);
}
Run Code Online (Sandbox Code Playgroud)


dot*_*NET 6

对。如果您不希望任何代码隐藏,也不需要复杂的字形计算,请使用以下XAML:

<RibbonApplicationMenu.SmallImageSource>
  <DrawingImage>
    <DrawingImage.Drawing>
      <GeometryDrawing>
        <GeometryDrawing.Geometry>
          <RectangleGeometry Rect="0,0,20,20"></RectangleGeometry>
        </GeometryDrawing.Geometry>
        <GeometryDrawing.Brush>
          <VisualBrush Stretch="Uniform">
            <VisualBrush.Visual>
                <TextBlock Text="File" FontSize="16" Foreground="White" />
            </VisualBrush.Visual>
          </VisualBrush>
        </GeometryDrawing.Brush>
      </GeometryDrawing>
    </DrawingImage.Drawing>
  </DrawingImage>
</RibbonApplicationMenu.SmallImageSource>
Run Code Online (Sandbox Code Playgroud)

这种方法的优点:

  • 仅XAML,无代码隐藏
  • 没有字形测量
  • 易于更换标签