如何在选择项目后阻止WP7上下文菜单关闭?

时间:2012-01-03 05:22:09

标签: silverlight windows-phone-7.1 windows-phone-7

我已经在一个列表框项目中连接了一个上下文菜单项,这样点击它就会改变它的状态。我需要菜单在选择项目后保持打开状态,或者在关闭后立即以编程方式重新打开菜单。

我的菜单如下:

Some Command 1
Some Command 2
Some Command 3
Inverted

用户可以点击Inverted命令,然后点击其他命令之一使其在反转模式下运行,菜单通过数据绑定如下所示:

Some Command 1
Some Command 2
Some Command 3
Inverted ✔ 

无法弄清楚如何在点击后保持菜单打开,我尝试了不那么理想的重新打开菜单方式:

private void onCommandInvert(object sender, RoutedEventArgs e)
{
  CommandState.Instance.Inverted = !CommandState.Instance.Inverted;

  // Open it again.
  MenuItem menuItem = (MenuItem)sender;
  ContextMenu menu = (ContextMenu)menuItem.Parent;
  menu.IsOpen = true;
}

但这样做会在menu.IsOpen = true语句中抛出以下异常:

A first chance exception of type 'System.InvalidOperationException' occurred in 
  System.Windows.dll

An unhandled exception of type 'System.InvalidOperationException' occurred in 
  System.Windows.dll

Additional information: Element is already the child of another element.

我还尝试了以下Closed事件,发生了同样的异常:

private void onContextMenuClosed(object sender, RoutedEventArgs e)
{
  ContextMenu menu = (ContextMenu)sender;
  menu.IsOpen = true;
}

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:0)

我明白了!感谢willmel的评论,我挖掘了MenuItem的源代码,并能够覆盖OnClick()来完全按照我的需要做到(毫无疑问是理想的解决方案)。但我无法访问Click,因此我还需要引入StayClick事件属性。

享受!

using Microsoft.Phone.Controls;
using System.Windows;

namespace MyNamespace
{
  public class MenuItemEx : MenuItem
  {
    public bool StayOpenWhenClicked
    {
      get;
      set;
    }

    public event RoutedEventHandler StayClick;

    protected override void OnClick()
    {
      if (StayOpenWhenClicked)
      {
        if (StayClick != null)
        {
          StayClick.Invoke(this, new RoutedEventArgs());
        }
      }
      else
      {
        base.OnClick();
      }
    }
  }
}

并在页面的xaml中,而不是toolkit:MenuItem,您使用my:MenuItemEx

<my:MenuItemEx 
  Header="Inverted"             
  StayClick="onCommandInvert"
  StayOpenWhenClicked="True"
/>

答案 1 :(得分:0)

如果您想在用户选择项目后保留菜单,那么我相信上下文菜单控件不是您应该使用的。

最好你应该创建自己的用户控件来模仿行为,并将其放置在有意义的屏幕上(在侧面或上方/下方)

或者,如果这些是要在所选项目上制定的选项,请考虑使用应用程序栏图标/菜单项并编写事件代码以读取列表框项目的当前选定值。

希望这有帮助。