【发布时间】:2013-11-20 22:36:31
【问题描述】:
我尝试在 LongListSelector 中实现自定义 ContextMenu。
我没有使用Microsoft.Phone.Controls.Toolkit中的ContextMenu,它与Rowi App中的基本相同:
(来源:hiddenpineapple.com)
方法 1
我的列表项将 VisualState 切换为保持状态,并显示一个带有控件的叠加层。
问题
当用户在列表项之外单击时(如在默认的 ContextMenu 中),我找不到返回默认状态的方法。
方法2
我已经为工具包 ContextMenu 实现了一个自定义模板,它看起来完全一样。我不得不将其边距顶部移动到-itemHeight,因为默认情况下它位于项目下方。
问题
这个解决方案的问题是,它在打开时会自动关闭,我不知道如何避免这种情况。
另一个问题是它不能很好地与工具包中的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 的提示。
【问题讨论】:
标签: xaml windows-phone-8