当我尝试多次显示菜单的同一实例时,ContextMenu位置是不可预测的



我需要在特定位置显示ContextMenu,并且第一次效果很好。如果我移动鼠标光标并尝试显示相同的 ContextMenu,那么即使 HorizontalOffsetVerticalOffset是硬编码的,它也可能在不同的位置显示。

如何在不每次重新定位的情况下在特定位置打开ContextMenu

System.Windows.Controls.Input.Toolkit版本:5.0.5.0

xaml

<Grid x:Name="LayoutRoot" Background="White"
      MouseRightButtonUp="LayoutRoot_MouseRightButtonUp"
      MouseRightButtonDown="LayoutRoot_MouseRightButtonDown"/>

代码

private ContextMenu menu;
private void LayoutRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
    if (menu == null)
    {
        menu = new ContextMenu();
        menu.Items.Add("test");
    }
    menu.HorizontalOffset = 100;
    menu.VerticalOffset = 100;
    menu.IsOpen = true;
}
private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
    e.Handled = true;
}

contextMenu中似乎有一个错误。它不会在第一次点击时拾取鼠标指针位置。

这是一个解决方法:

private void LayoutRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
    if (menu == null)
    {
        menu = new ContextMenu();
        menu.Items.Add("test");
        menu.HorizontalOffset = 100;
        menu.VerticalOffset = 100;
    }
    else
    {
        menu.HorizontalOffset = 100 - e.GetPosition(null).X;
        menu.VerticalOffset = 100 - e.GetPosition(null).Y;                
    }
    menu.IsOpen = true;
}

更新:

我仔细观察了拆卸的来源,看来一旦显示了contextMenu,启用了mousetracking,这就是为什么我们需要调整偏移以取消conteactMenu的效果,以便基于基于其位置的效果最后一个Mousemove活动,不是最后一个Mouserightbuttonup的位置。这是一个修订的代码示例来说明:

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
        LayoutRoot.MouseRightButtonDown += LayoutRoot_MouseRightButtonDown;
        LayoutRoot.MouseRightButtonUp += LayoutRoot_MouseRightButtonUp;
        LayoutRoot.MouseMove += LayoutRoot_MouseMove;
        SetupContextMenu();
    }
    private void SetupContextMenu()
    {
        if (menu == null)
        {
            menu = new ContextMenu();
            menu.Items.Add("test");
            ContextMenuService.SetContextMenu(this, menu);
        }
    }
    private ContextMenu menu;
    private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
    {
        var mousePosition = e.GetPosition(this);
        menu.HorizontalOffset = 100 - mousePosition.X;
        menu.VerticalOffset = 100 - mousePosition.Y;
    }
    private void LayoutRoot_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
    {
        menu.IsOpen = true;
    }
    private void LayoutRoot_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        e.Handled = true;
    }
}

最新更新