Menü Schließen

Workaround for the „File“ Bug in the WPF RibbonControlsLibrary

This post shows how to overcome an annoying bug in the Microsoft RibbonControlsLibrary.

When you define the ribbon and change the label of the „File“ menu, the changed text is not shown, instead you’ll always see the „File“ text. Especially when you want to define your own localized strings, this can be a show stopper.

The first tip that I have i not to use the RibbonControlsLibrary 🙂

Use the Fluent library instead. It’s free, also for commercial use:

https://fluentribbon.github.io/

If this is your solution, then you can already stop reading the post. But if you cannot or don’t want to switch the library, you can use the following code to fix the issue:

// Constructor:
public MainWindow() 
{
  InitializeComponent();
  this.Loaded += (sender, e) => {
    replaceRibbonApplicationMenuButtonContent(menu);
  };
}

private void replaceRibbonApplicationMenuButtonContent(RibbonApplicationMenu menu) 
{
  var outerGrid = (Grid)VisualTreeHelper.GetChild(menu, 0);
  var toggleButton = (RibbonToggleButton)outerGrid.Children[0];
  replaceRibbonToggleButtonContent(toggleButton, menu.Label);
  var popup = (Popup)outerGrid.Children[2];
  EventHandler popupOpenedHandler = null;
  popupOpenedHandler = new EventHandler(delegate {
    var decorator = (Decorator)popup.Child;
    var popupGrid = (Grid)decorator.Child;
    var canvas = (Canvas)popupGrid.Children[1];
    var popupToggleButton = (RibbonToggleButton)canvas.Children[0];
    replaceRibbonToggleButtonContent(popupToggleButton, menu.Label);
    popup.Opened -= popupOpenedHandler;
  });
  popup.Opened += popupOpenedHandler;
}

private void replaceRibbonToggleButtonContent(RibbonToggleButton toggleButton, string text) 
{
  var grid = (Grid)VisualTreeHelper.GetChild(toggleButton, 0);
  var border = (Border)grid.Children[1];
  border.Opacity = .5;
  var stackPanel = (StackPanel)grid.Children[2];
  var children = stackPanel.Children;
  children.RemoveRange(0, children.Count);
  var textBlock = new TextBlock(new Run(text));
  textBlock.Foreground = Brushes.White;
  children.Add(textBlock);
}

The code uses the VisualTreeHelper to walk through the visual tree to find the necessary elements and „inject“ a new TextBlock at runtime. As the WPF visual tree is only there when the window is initialized and loaded, we need to use the Loaded event to delay execution of the code.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert