问题
Is it possible to modify the application menu's drop position for the 10/2010 WPF ribbon? I think it's very unusual that a menu opens at the leftmost position, so I'd like to change that.
Example: in Word 2007 (which - as you probable all know - has the old ribbon design) the application menu opens as far as possible to the right. I'd like to get this behaviour, too, because at the right is the only sensible position for the menu. All its entries are in the left column, which was right below the button then. I've not found any easy way to assign its left position. Does anybody know if and how this is possible?
回答1:
Okay, after many hours of try and error, I found a possible way to do it. It's not the 100% original behaviour like in "Windows 7 Paint" or similar Windows 7 ribbon applications, but in most cases it works.
First, you need to know that the application menu is realized with a Popup
, which has a Placement
property to define where the popup is opened. You need to override the default behaviour to PlacementMode.Left
. This will make the popup menu open up right next to the menu button.
Next, you need to set the Popup.HorizontalOffset
property to the negated RibbonApplicationMenu.Width
. This is done via Binding and a converter to negate the value.
<r:RibbonApplicationMenu>
<r:RibbonApplicationMenu.Resources>
<Style TargetType="Popup">
<Setter Property="Placement" Value="Left"/>
<Setter Property="HorizontalOffset" Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=r:RibbonApplicationMenu}, Path=Width, Converter={StaticResource ResourceKey=NegateIntegerConverter}}"/>
</Style>
</r:RibbonApplicationMenu.Resources>
</r:RibbonApplicationMenu>
The converter is defined in the RibbonWindow.Resources
as follows:
<r:RibbonWindow.Resources>
<local:NegateIntegerConverter x:Key="NegateIntegerConverter"/>
</r:RibbonWindow.Resources>
The local
namespace has to be declared inside of the RibbonWindow
:
<r:RibbonWindow x:Class="MainWindow"
xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:local="clr-namespace:ApplicationRootNamespace"
>
And finally, the code for the NegateIntegerConverter
is a class in the application's root namespace:
Public Class NegateIntegerConverter
Implements IValueConverter
Public Function Convert(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
Return -CInt(value)
End Function
Public Function ConvertBack(value As Object, targetType As System.Type, parameter As Object, culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
Return -CInt(value)
End Function
End Class
Class MainWindow
End Class
Now for the difference in behaviour: if the menu cannot fully expand to the right because the screen is ending there, the popup does not simply open up a bit farther to the left, but completely on the left. Maybe I can find out how it's actually behaving like the "Windows 7 Paint" ribbon's menu, but this is a good workaround until then.
来源:https://stackoverflow.com/questions/14111463/how-can-i-modify-the-wpf-ribbon-application-menu-dropdown-position