ContextMenu的奇怪行为:放置";镜像”;
本文关键字:quot 镜像 放置 ContextMenu | 更新日期: 2024-07-27 20:09:33
在使用ContextMenu时,我遇到了一个非常奇怪的行为(至少对我来说)。以下是简化的xaml(MainWindow.xml):
<Window x:Class="ContextMenuTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="500"
Height="300">
<Button Content="Do this" Height="25" Width="80" ContextMenuService.Placement="Right">
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="Do this" />
<MenuItem Header="Do that" />
</ContextMenu>
</Button.ContextMenu>
</Button>
</Window>
使用此xaml,右键单击按钮的预期结果是位于按钮右侧的ContextMenu。但结果是:
https://i.stack.imgur.com/pSd0Q.png
因此,ContextMenu奇怪地位于按钮的左侧。我还尝试将属性ContextMenuService.Placement
设置为Left
、Top
、Bottom
。结果是:
Left
->ContextMenu位于按钮的右侧Top
->ContextMenu位于按钮的右上方。(非顶部-左侧)Bottom
->ContextMenu位于按钮的底部-右侧(而不是底部-左侧)
在我看来,坐标系是镜像的(也就是说,坐标系的原点在窗口的右上角,而不是左上角)。我不知道为什么。我需要帮助将ContextMenu放置在按钮的左下角。
(附言:此示例项目与Visual Studio 2013创建的默认项目相同,除了MainWindow.xaml。)
好的,我终于找到了解决方案(是的,终于)。这个问题可能与这里描述的问题同构:带有弹出的WPF Handedness
所以我写了一个行为:
namespace Test {
public class WorkaroundForTheBugOfPopupBehavior : Behavior<FrameworkElement> {
private static readonly FieldInfo _menuDropAlignmentField;
static WorkaroundForTheBugOfContextMenuBehavior() {
_menuDropAlignmentField = typeof(SystemParameters).GetField("_menuDropAlignment", BindingFlags.NonPublic | BindingFlags.Static);
System.Diagnostics.Debug.Assert(_menuDropAlignmentField != null);
EnsureStandardPopupAlignment();
SystemParameters.StaticPropertyChanged += OnStaticPropertyChanged;
}
private static void EnsureStandardPopupAlignment() {
if (SystemParameters.MenuDropAlignment && _menuDropAlignmentField != null) {
_menuDropAlignmentField.SetValue(null, false);
}
}
private static void OnStaticPropertyChanged(object sender, PropertyChangedEventArgs e) {
EnsureStandardPopupAlignment();
}
}
}
并将其连接到主窗口:
<i:Interaction.Behaviors>
<local:WorkaroundForTheBugOfPopupBehavior />
</i:Interaction.Behaviors>
其中:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:Test"
问题已经过去了。希望这能帮助其他人。。。