简体   繁体   English

WP8的自定义上下文菜单XAML

[英]Custom context menu XAML for WP8

I try to implement a custom ContextMenu in a LongListSelector . 我尝试在LongListSelector实现自定义ContextMenu。

I'm not using the ContextMenu from Microsoft.Phone.Controls.Toolkit , it's basically the same as in the Rowi App: 我没有使用Microsoft.Phone.Controls.ToolkitContextMenu ,它与Rowi App中的基本上相同:


(source: hiddenpineapple.com ) (来源: hiddenpineapple.com

Approach 1 方法1

My list item toggles a VisualState on hold and an overlay is shown with controls in it. 我的列表项将VisualState切换为保留状态,并显示一个带有控件的覆盖图。

The problem 问题

I can't find a way to go back to the default state when the user clicks outside of the list item (as in the default ContextMenu). 当用户在列表项之外单击时(如默认的ContextMenu一样),我找不到返回默认状态的方法。

Approach 2 方法2

I've implemented a custom template for the toolkit ContextMenu which looks exactly the same. 我为工具箱ContextMenu实现了一个自定义模板,它看起来完全一样。 I had to move its margin top to -itemHeight , as by default it is below the item. 我必须将其边距顶部移至-itemHeight ,因为默认情况下它位于该项目下方。

The problem 问题

The problem with this solution is, that it automatically closes itself when opening and I couldn't figure out how to avoid this. 该解决方案的问题在于,它在打开时会自动关闭,我不知道该如何避免。
Another problem was that it didn't work well with TiltEffect.IsTiltEnabled from the Toolkit (visual problems). 另一个问题是,它与Toolkit中的TiltEffect.IsTiltEnabled一起使用时效果TiltEffect.IsTiltEnabled (视觉问题)。

I need your help 我需要你的帮助

Any suggestions on how to get this working? 关于如何使它工作的任何建议?


Answer 回答

Thanks to Cheese , now I know how to properly close the menu when the user clicks outside. 多亏了Cheese ,现在我知道当用户在外面单击时如何正确关闭菜单。 His suggestion was to get the coordinates of a Tap event on the current page, and check if it's inside the menu. 他的建议是获取当前页面上Tap事件的坐标,并检查它是否在菜单内。 When not, close the menu. 否则,请关闭菜单。

So I added a Tap listener to the page when the menu opens, and removed it when the menu closes. 因此,我在菜单打开时向页面添加了Tap侦听器,并在菜单关闭时将其删除。 From the page listener I got the event coordinates and could check if it's inside the control which holds the menu (same size and position). 从页面侦听器中,我得到了事件坐标,并可以检查它是否在包含菜单的控件内(大小和位置相同)。 I received the position of the control with Point leftUpperPoint = control.TransformToVisual(page).Transform(new Point(0, 0)) and the rightLowerPoint by adding the ActualWidth and ActualHeight. 通过添加ActualWidth和ActualHeight,我收到了Point leftUpperPoint = control.TransformToVisual(page).Transform(new Point(0, 0))rightLowerPoint的位置。

But then I realized: 但是后来我意识到:

Why should I even calculate if the tap is inside the menu? 为什么还要计算水龙头是否在菜单内? I always want to close the menu when the user taps anywhere on the screen. 我总是想在用户点击屏幕上的任何位置时关闭菜单。 If it's outside, yes . 如果在外面, 是的 If it's on a menu button, yes . 如果在菜单按钮上, 则为

Another modification I made was to listen for MouseLeftButtonDown instead of Tap as it also triggers when the user swipes. 我进行的另一个修改是监听MouseLeftButtonDown而不是Tap因为它在用户滑动时也会触发。

So I removed this code and came up with the following: 所以我删除了这段代码,并提出了以下内容:

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

This works perfectly! 这样完美!

Thanks to Cheese for the hint. 感谢Cheese的提示。

Approach 1 problem 方法1的问题

The best solution would be: 最好的解决方案是:

Get the menus coordinates, when user makes a tap - you check are tap coordinates on menu or not, if not - dissmiss - simple. 获取菜单坐标,当用户点击时-您检查菜单上的点击坐标是否存在,否则查看-取消-简单。

Approach 2 problem 方法2问题

I guess you had some button in a corner and when you tapped on it - nothing happened? 我想您在角落里有一些按钮,当您轻按它时-什么都没发生? And when you dissmissed the Tilt all worked. 而当您解雇Tilt时,一切都奏效了。 It seems that tilt works faster than a click, so, tilt changes the button coordinates, and device thiks you have missed/or dragged off 倾斜似乎比单击更快,因此,倾斜会更改按钮坐标以及您错过/或拖过的设备提示

You can use what @ScottIsAFool suggested and maybe create another Dependency Property on your TapMenu control of type UIElement named CloseWhenTappedElement and automatically listen for Tap events inside your control once set. 您可以使用@ScottIsAFool的建议,还可以在UIElement类型的TapMenu控件上创建另一个名为CloseWhenTappedElement的Dependency属性,并在设置后自动监听控件内的Tap事件。 For example 例如

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM