Как установить текст в заголовке RibbonApplicationMenu - PullRequest
23 голосов
/ 14 июля 2011

Я пытаюсь получить текст на верхнем уровне 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 ]

21 голосов
/ 19 июля 2011

Самым простым решением (для меня) было вставить DrawingImage с GlyphRun внутри.На отдельном посте спрашивается, как получить AdvanceWidths и GlyphIndicies для GlyphRun.Результат ниже

<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

13 голосов
/ 18 июля 2011

Удалите ненужные элементы для визуального дерева и замените их 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);
}
4 голосов
/ 25 октября 2017

правый.Если вам не нужны кодовый код и сложные вычисления глифов, используйте следующий 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 голосов
/ 14 июля 2011

Tricky!Возможно, вам придется заменить PART_ToggleButton шаблона своей собственной версией, чтобы иметь возможность установить текст.

Использование WPF Vizualizer показывает, что шаблон содержит StackPanel с изображением иPath (DownArrow), но нет TextBlock, поэтому я сомневаюсь, что в текущем элементе управления есть место для указания текста метки.

Конечно, вы также можете создать изображение, которое содержит нужный текст.

1 голос
/ 16 февраля 2012

Еще один способ сделать это - просто использовать сетку и нарисовать TextBlock в нужном месте.Обязательно сделайте TextBlock НЕ 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 голосов
/ 25 апреля 2019

Следующее решение было размещено на форуме MSDN . Это включает изменение стиля, используемого в теме по умолчанию (?).

Я проверил исходный код элементов управления ленты (пожалуйста, загрузите MicrosoftRibbonForWPFSourceAndSamples с веб-сайта ). в файл темы (\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}» HorizontalAlignment = "Центр" VerticalAlignment = "Центр" Ширина = "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}"
Style = "{StaticResource Ü}" Focusable = "False" Высота = "{Binding RelativeSource = {RelativeSource TemplatedParent}, путь = Высота}" Width = "{Binding RelativeSource = {RelativeSource TemplatedParent}, Path = Width}" Label = "{TemplateBinding Label}" /> А в RibbonWindow мы могли бы установить свойство Label RibbonApplicationMenu как:

<ribbon:RibbonApplicationMenu Label="File">

Сообщение на форуме содержало ZIP с измененными источниками, но ссылка больше не работает.

...