2011-07-14 21 views
21

Estoy tratando de tener texto en el nivel superior de un RibbonApplicationMenu (tratando de obtener la palabra "Archivo" allí similar a Word o Outlook). Parece que Microsoft.Windows.Controls.Ribbon.RibbonApplicationMenuhttp://msdn.microsoft.com/en-us/library/microsoft.windows.controls.ribbon.ribbonapplicationmenu.aspx es compatible con SmallImageSource pero no tiene propiedad de texto. Establecer la propiedad Label no funciona para este problema.Cómo configurar texto al principio de un RibbonApplicationMenu

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

</ribbon:RibbonApplicationMenu> 

El objetivo es que aparezca la palabra "Archivo" en el área del círculo a continuación.

RibbonApplicationMenu

+5

Microsoft necesita reparar esto. – 00jt

Respuesta

21

La solución más simple (para mí) era insertar un DrawingImage con un GlyphRun interior. En un separate post se le pregunta cómo obtener los Anchos Avanzados y las Indicaciones de Glifos para el GlyphRun. El resultado está por debajo

<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> 

resultante de la cinta:

GlyphRun Result

+0

¿Pero cómo se puede hacer que su propio texto personalizado sea del tamaño correcto? me trataron: GlyphIndices = "79 79 43 72 82 3 58 82 85 79 71" AdvanceWidths = "9.62666666666667 7.41333333333333 2.96 2.96 7.41333333333333 3.70666666666667 12.5866666666667 7.41333333333333 4.44 2.96 7.41333333333333" Y es "Hello World" .. pero es súper pequeño – 00jt

+6

Esto es claramente algo que necesita ser arreglado ... que sólo debe ser: Etiqueta = "file" – 00jt

+7

@ 00jt 1. No puedo creer que tenga que poner esta cosa asquerosa para conseguir algo tan simple de trabajar (no digo que la respuesta no sea buena. De hecho, creo que es impresionante y sofisticado, es solo que Microsoft realmente lo arruinó aquí). – MasterMastic

2

difícil! Es posible que deba reemplazar el PART_ToggleButton de la plantilla con su propia versión para poder establecer el texto.

El uso del WPF Vizualizer muestra que la plantilla contiene un StackPanel con una imagen y una ruta (DownArrow), pero no TextBlock, así que dudo que haya un lugar en el control actual para especificar el texto de la etiqueta.

Por supuesto, también puede crear una imagen que contiene el texto deseado.

+0

Considero que crear una imagen que contenga solo el texto "Archivo" es un truco, pero probablemente funcione. –

+0

Vale la pena señalar los muchos inconvenientes del hack: el texto se verá borroso en los DPI distintos de 96; Los ajustes de texto de ClearType no funcionarán; más difícil de localizar; no valdrá la pena con los lectores de pantalla. –

13

Elimine los elementos no deseados para el árbol visual y reemplácelos con un TextBlock que toma el texto de la propiedad Label. Tienes que hacer esto tanto para el botón en el árbol visual principal como en el árbol visual de la ventana emergente. Finalmente, dado que el texto es más complicado que la imagen típica, es útil retroceder en los efectos de resaltado aerodinámico.

Para usar el siguiente código, asigne un nombre al menú de la aplicación en el XAML y llame al ReplaceRibbonApplicationMenuButtonContent con él desde el controlador de eventos cargado de la ventana.

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

De lejos, esta debería ser la solución aceptada ... –

1

Otra forma de hacerlo es simplemente el uso de una rejilla y pintar un TextBlock en el lugar correcto. Asegúrese de hacer que TextBlock NO sea 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> 

Ventajas:

  • menos xaml
  • manera más fácil de localizar

Desventaja: - parece menos agradable en Windows XP

+1

Intenté su opción, pero cuando hago clic en RibbonApplicationMenu el texto está oculto. Solo muestra "Archivo" si no muestra el menú desplegable. – 00jt

+0

tiene razón al respecto ... podría volver a utilizar un TextBlock en el menú RibbonMenu, pero no creí que fuera muy importante –

0

derecho.Si no desea código subyacente y no hay cálculos de glifos complejos, utilice el siguiente 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> 

ventajas de este enfoque:

  • XAML-solamente, no hay código subyacente
  • Ninguna medida glifo
  • Fácil de cambiar etiqueta
Cuestiones relacionadas