さて、何時間もの試行錯誤の末、可能な方法を見つけました。「Windows 7 ペイント」や同様の Windows 7 リボン アプリケーションのような 100% オリジナルの動作ではありませんが、ほとんどの場合は機能します。
まず、アプリケーション メニューが で実現されていることを知っておく必要がありますPopup
。これにはPlacement
、ポップアップを開く場所を定義するプロパティがあります。デフォルトの動作を にオーバーライドする必要がありますPlacementMode.Left
。これにより、メニューボタンのすぐ隣にポップアップメニューが開きます。
次に、Popup.HorizontalOffset
プロパティを negatedに設定する必要がありますRibbonApplicationMenu.Width
。これは、Binding と値を無効にするコンバーターを介して行われます。
<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>
コンバーターは、 で次のように定義さRibbonWindow.Resources
れます。
<r:RibbonWindow.Resources>
<local:NegateIntegerConverter x:Key="NegateIntegerConverter"/>
</r:RibbonWindow.Resources>
名前local
空間は、次の内部で宣言する必要がありますRibbonWindow
。
<r:RibbonWindow x:Class="MainWindow"
xmlns:r="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:local="clr-namespace:ApplicationRootNamespace"
>
最後に、 のコードはNegateIntegerConverter
、アプリケーションのルート名前空間のクラスです。
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
ここで、動作の違いについて説明します。画面がそこで終了しているためにメニューが右に完全に展開できない場合、ポップアップは単に少し左に開くのではなく、完全に左に開きます。「Windows 7 Paint」リボンのメニューのように実際にどのように動作しているかを知ることができるかもしれませんが、それまではこれが良い回避策です。