如何在RibbonApplicationMenu的头部设置文本

问题描述 投票:23回答:6

我正在尝试将文本放在RibbonApplicationMenu的顶层(尝试获取类似于Word或Outlook的单词“File”)。似乎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>

目标是在下面的圆圈区域中显示“文件”一词。

wpf ribbon ribbon-control ribboncontrolslibrary
6个回答
21
投票

最简单的解决方案(对我来说)是插入一个带有DrawingImageGlyphRun。在separate post上询问如何获取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>

结果功能区:


13
投票

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

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

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

4
投票

对。如果您不需要代码隐藏,也不需要复杂的字形计算,请使用以下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>

这种方法的优点:

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

2
投票

整蛊!您可能必须使用您自己的版本替换模板的PART_ToggleButton才能设置文本。

使用WPF Vizualizer显示模板包含带有Image和Path(DownArrow)的StackPanel,但没有TextBlock,所以我怀疑当前控件中有一个位置来指定标签文本。

当然,您也可以创建包含所需文本的图像。


1
投票

另一种方法是使用网格并在正确的位置绘制TextBlock。一定要使TextBlock Not HitTestVisible。

<Grid>
    <DockPanel>
         <ribbon:Ribbon DockPanel.Dock="Top">
             <!-- your ribbon stuff -->
         </ribbon:Ribbon>
         <!-- your other stuff -->
    </DockPanel>
    <TextBlock Margin="3,26" Foreground="White"
               IsHitTestVisible="False"
               Text="{LocalizeExtension:LocText Key=FILE, Dict=Strings, Assembly=YourAssembly}"/>
</Grid>

好处:

  • 少xaml
  • 更容易本地化

缺点: - 在Windows XP上看起来不太好看


0
投票

以下解决方案发布了on an MSDN forum。它涉及更改默认(?)主题中使用的样式。

我检查了Ribbon控件的源代码(请下载MicrosoftRibbonForWPFSourceAndSamples from web site)。在功能区的主题文件(\MicrosoftRibbonForWPFSourceAndSamples\RibbonControlsLibrary\Themes\Generic.xaml)中,您可以发现这种风格“&#220;”用于RibbonApplicationMenu。在这种风格中,没有要显示Text的元素,它只有一个Image元素来显示图像。

幸运的是,我们可以修改样式代码并在“&#220;”样式中添加一些控件。请在下面的代码:

第7264行,更改代码:

 <!--<Image IsHitTestVisible="False"
    Source="{Binding RelativeSource ={RelativeSource FindAncestor, AncestorType ={x:Type ribbon:RibbonApplicationMenu}},

Path = SmallImageSource}“Horizo​​ntalAlignment =”Center“VerticalAlignment =”Center“Width =”16“Height =”16“RenderOptions.BitmapScalingMode =”NearestNeighbor“RenderOptions.EdgeMode =”Aliased“/> - >

第7433行,在Label="{TemplateBinding Label}"元素的末尾添加代码RibbonToggleButton

 ......
 <ControlTemplate TargetType="{x:Type ribbon:RibbonApplicationMenu}">
   <Grid Focusable="False"
      x:Name="OuterGrid"
      SnapsToDevicePixels="True">
     <ribbon:RibbonToggleButton x:Name="PART_ToggleButton" 
       BorderBrush="{TemplateBinding BorderBrush}"
       Background="{TemplateBinding Background}"
       BorderThickness="{TemplateBinding BorderThickness}"                       
       Style="{StaticResource &#220;}"
       FocusVisualStyle="{TemplateBinding FocusVisualStyle}"
       Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Height}"
       Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
       ToolTipTitle="{TemplateBinding ToolTipTitle}"
       ToolTipDescription="{TemplateBinding ToolTipDescription}"
       ToolTipImageSource="{TemplateBinding ToolTipImageSource}"
       ToolTipFooterTitle="{TemplateBinding ToolTipFooterTitle}"
       ToolTipFooterDescription="{TemplateBinding ToolTipFooterDescription}"
       ToolTipFooterImageSource="{TemplateBinding ToolTipFooterImageSource}"
       SmallImageSource="{TemplateBinding SmallImageSource}"
       IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsDropDownOpen, Mode=TwoWay}"
       Label="{TemplateBinding Label}"/>

第7564行,在Label="{TemplateBinding Label}"元素的末尾添加代码RibbonToggleButton

......
<Canvas>
  <ribbon:RibbonToggleButton x:Name="PART_PopupToggleButton"
    AutomationProperties.Name="{Binding RelativeSource={RelativeSource TemplatedParent},

Path =(AutomationProperties.Name)}“Canvas.Top =” - 24“Canvas.Left =”3“IsChecked =”{Binding RelativeSource = {RelativeSource TemplatedParent},Path = IsDropDownOpen}“BorderBrush =”{TemplateBinding BorderBrush}“Background =“{TemplateBinding Background}”BorderThickness =“{TemplateBinding BorderThickness}” Style =“{StaticResourceÜ}”Focusable =“False”Height =“{Binding RelativeSource = {RelativeSource TemplatedParent},Path = Height}”Width =“{Binding RelativeSource = {RelativeSource TemplatedParent},Path = Width}”Label =“ {TemplateBinding Label}“/>在RibbonWindow中,我们可以将RibbonApplicationMenu的Label属性设置为:

<ribbon:RibbonApplicationMenu Label="File">

论坛帖子确实包含了修改后来源的ZIP,但链接不再有效。

© www.soinside.com 2019 - 2024. All rights reserved.