如何在RibbonApplicationMenu的头部设置文本

时间:2011-07-14 18:30:10

标签: 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>

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

RibbonApplicationMenu

6 个答案:

答案 0 :(得分:21)

最简单的解决方案(对我而言)是在DrawingImage内插入一个GlyphRun。在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>

结果功能区:

GlyphRun Result

答案 1 :(得分:13)

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

要使用以下代码,请为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);
}

答案 2 :(得分:4)

右。如果您不需要代码隐藏并且不需要复杂的字形计算,请使用以下XAML:

{{1}}

这种方法的优点:

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

答案 3 :(得分:2)

棘手!您可能需要使用自己的版本替换模板的 PART_ToggleButton 才能设置文本。

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

当然,您也可以创建包含所需文字的图片

答案 4 :(得分: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>

优点:

  • less xaml
  • 更容易本地化

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

答案 5 :(得分:0)

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

  

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

     

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

     

第7264行,更改代码:

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

Path = SmallImageSource}”           Horizo​​ntalAlignment =“ Center”           VerticalAlignment =“ Center”           宽度=“ 16”           身高=“ 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}”
          样式=“ {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,但该链接不再有效。