WP8的自定义上下文菜单XAML

时间:2013-11-20 22:36:32

标签: xaml windows-phone-8

我尝试在LongListSelector中实现自定义ContextMenu。

我没有使用ContextMenu中的Microsoft.Phone.Controls.Toolkit,它与Rowi App中的基本相同:

http://static.hiddenpineapple.com/images/rowi-phone.png

方法1

我的列表项切换保持的VisualState,并显示一个叠加控件。

问题

当用户点击列表项外部时(例如默认的ContextMenu中),我找不到回到默认状态的方法。

方法2

我已经为工具包ContextMenu实现了一个自定义模板,它看起来完全一样。我必须将其边距移到-itemHeight,因为默认情况下它位于项目下方。

问题

这个解决方案的问题是,它在打开时自动关闭,我无法弄清楚如何避免这种情况。
另一个问题是它与Toolkit中的TiltEffect.IsTiltEnabled(视觉问题)不兼容。

我需要你的帮助

有关如何使其正常工作的任何建议吗?


答案

感谢Cheese,现在我知道当用户点击外部时如何正确关闭菜单。 他的建议是在当前页面上获取Tap事件的坐标,并检查它是否在菜单中。如果没有,请关闭菜单。

所以我在菜单打开时向页面添加了一个Tap监听器,并在菜单关闭时将其删除。从页面监听器我得到了事件坐标,并可以检查它是否在控件内部(相同的大小和位置)。我通过添加ActualWidth和ActualHeight,使用Point leftUpperPoint = control.TransformToVisual(page).Transform(new Point(0, 0))rightLowerPoint收到了控件的位置。

但后来我意识到:

为什么我甚至要计算水龙头是否在菜单内?当用户点击屏幕上的任何位置时,我总是想要关闭菜单。如果它在外面,。如果它在菜单按钮上,

我做的另一个修改是收听MouseLeftButtonDown而不是Tap,因为当用户滑动时它也会触发。

所以我删除了这段代码并提出了以下内容:

private void ToggleMenu(object sender, System.Windows.Input.GestureEventArgs e)
{
  PhoneApplicationFrame frame = ((PhoneApplicationFrame)Application.Current.RootVisual);
  VisualState state = this.States.CurrentState;

  if (state == null || state.Name == "DefaultState")
  {
    frame.MouseLeftButtonDown += MouseDownDelegate;
    this.State = "MenuState";
  }
  else
  {
    frame.MouseLeftButtonDown -= MouseDownDelegate;
    this.State = "DefaultState";
  }
}

private void MouseDownDelegate(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
  ToggleMenu(sender, null);
}

这完美无缺!

感谢Cheese提示。

3 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

接近1问题

最好的解决方案是:

获取菜单坐标,当用户点击时 - 您检查是否是菜单上的点击坐标,如果不是 - 忽略 - 简单。

接近2问题

我猜你在角落里有一些按钮,当你点击它时 - 什么都没发生?当你解散Tilt时,所有工作。似乎倾斜比点击​​更快,因此,倾斜会改变按钮坐标,并且设备会让您错过/或拖出

答案 2 :(得分:0)

您可以使用@ScottIsAFool建议的内容,也可以在名为CloseWhenTappedElement的类型为UIElement的TapMenu控件上创建另一个依赖属性,并在设置后自动侦听控件中的Tap事件。例如

<Grid x:Name="TapArea"/>
<TapMenu CloseWhenTappedElement="{Binding ElementName=TapArea"}/>