ContextMenu的奇怪行为:placement"镜像"

时间:2015-02-22 12:02:59

标签: c# wpf xaml contextmenu

使用ContextMenu时,我遇到了一种非常奇怪的行为(至少对我而言)。这是简化的xaml(MainWindow.xaml):

<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。但结果是:

http://i.stack.imgur.com/pSd0Q.png

因此,ContextMenu奇怪地放置在按钮的 left 上。我还尝试将属性ContextMenuService.Placement设置为LeftTopBottom。结果是:

  • Left - &gt; ContextMenu位于按钮的 right
  • Top - &gt; ContextMenu位于按钮的top- right 。 (不是top-
  • Bottom - &gt; ContextMenu位于按钮的底部 - 右侧(不是底部 - 左侧

在我看来,坐标系是镜像(也就是说,坐标系的原点位于窗口的右上角,而不是左上角)。我根本不知道为什么。我需要帮助将ContextMenu放在按钮的左下角。

(P.S。此示例项目与Visual Studio 2013创建的默认项目相同,但MainWindow.xaml除外。)

1 个答案:

答案 0 :(得分:0)

好的,我终于(是的,终于)找到了解决方案。问题可能与此处描述的问题同构:WPF Handedness with Popups

所以我写了一个行为:

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();
    }
  }
}

...并将其附加到MainWindow:

  <i:Interaction.Behaviors>
    <local:WorkaroundForTheBugOfPopupBehavior />
  </i:Interaction.Behaviors>

其中:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:local="clr-namespace:Test"

问题已经消失。希望这有助于其他人...