2011-07-14 12 views
21

Próbuję mieć tekst na najwyższym poziomie RibbonApplicationMenu (próbuje uzyskać słowo "Plik" podobne do Word lub Outlook). Wygląda na to, że Microsoft.Windows.Controls.Ribbon.RibbonApplicationMenuhttp://msdn.microsoft.com/en-us/library/microsoft.windows.controls.ribbon.ribbonapplicationmenu.aspx obsługuje właściwość SmallImageSource, ale nie ma tekstu. Ustawienie właściwości Label nie działa w przypadku tego problemu.Jak ustawić tekst na początku RibbonApplicationMenu

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

</ribbon:RibbonApplicationMenu> 

Celem jest wyświetlenie słowa "Plik" w zakreślonym obszarze poniżej.

RibbonApplicationMenu

+5

Firma Microsoft musi to naprawić. – 00jt

Odpowiedz

21

Najprostszym rozwiązaniem (mi) było wstawić DrawingImage z GlyphRun wewnątrz. Na temat separate post jest pytanie, jak uzyskać AdvanceWidths i GlyphIndicies dla GlyphRun. Wynik jest poniżej

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

Resulting Wstążka:

GlyphRun Result

+0

Ale w jaki sposób uczynić go własnym niestandardowym tekstem mieć odpowiedni rozmiar? Próbowałem: GlyphIndices = "72 79 79 43 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" I to jest "Hello World", ale .. to jest bardzo małe. – 00jt

+6

Jest to wyraźnie coś, co musi zostać naprawione ... POWINIEN BYĆ: Label = "Plik" – 00jt

+7

@ 00jt +1. Nie mogę uwierzyć, że muszę umieścić tę brudną rzecz, aby uzyskać coś tak prostego w obsłudze (nie twierdzę, że odpowiedź nie jest dobra, uważam, że jest niesamowita i wyrafinowana, po prostu Microsoft naprawdę to sprowadził). – MasterMastic

2

Tricky! Być może trzeba będzie zastąpić szablon PARTNER z własną wersją, aby móc ustawić tekst.

Korzystanie z WPF Vizualizer pokazuje, że szablon zawiera StackPanel z obrazem i ścieżką (DownArrow), ale bez blokady TextBlock, więc wątpię, czy istnieje miejsce w bieżącej kontroli, aby określić tekst etykiety.

Oczywiście można również utworzyć obraz zawierający żądany tekst.

+0

Zastanawiałem się nad stworzeniem obrazu, który zawiera tylko tekst "File", ale może to zadziałać. –

+0

Warto zwrócić uwagę na liczne wady hackowania: tekst będzie wyglądał niewyraźnie w DPIs innych niż 96; Korekty tekstu ClearType nie będą działać; trudniej zlokalizować; nie będzie warta z czytnikami ekranu. –

13

Usuń niechciane elementy dla drzewa wizualnego i zastąp je blokadą tekstu, która pobiera tekst z właściwości Etykieta. Musisz to zrobić zarówno dla przycisku na głównym drzewie wizualnym, jak i na drzewie wizualnym popup. Wreszcie, ponieważ tekst jest bardziej skomplikowany niż typowy obraz, pomocne jest wycofanie się z efektów podświetlania aerodynamiki.

Aby użyć następującego kodu, przypisz nazwę do menu aplikacji w XAML i wywołaj z nim kod ReplaceRibbonApplicationMenuButtonContent z załadowanej obsługi zdarzeń okna.

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

Zdecydowanie to powinno być przyjęte rozwiązanie ... –

1

Innym sposobem na to jest po prostu za pomocą siatki i malować TextBlock na właściwym miejscu. Upewnij się, że 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> 

Zalety:

  • mniej XAML
  • sposób łatwiej zlokalizować

Wada: - wygląda mniej przyjemne w systemie Windows XP

+1

Próbowałem twojej opcji, ale kiedy klikam na RibbonApplicationMenu tekst jest ukryty. Pokazuje tylko "Plik", jeśli nie wyświetla menu rozwijanego. – 00jt

+0

masz rację, że ... możesz ponownie użyć TextBlock na pojawiającym się RibbonMenu, ale ja osobiście nie uważałem tego za bardzo ważne –

0

prawo.Jeśli chcesz żadnego kodu źródłowego i żadnych złożonych obliczeń glifów, należy użyć następującego 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> 

zalety tego podejścia:

  • XAML-tylko, bez kodu źródłowego
  • pomiar nie glif
  • Łatwa zmiana etykiety
Powiązane problemy