这个问题实际上是一样的描述如下: http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/542b827a-7c8e-4984-9158-9d8479b2d5b1但我并不满足于接受答案那里,觉得必须有一个更好的解决办法?
我想实现我的列表视图“CLASIC”上下文菜单(不是通过AppBar而是通过PopupMenu的),而且工作得很好,但只有当我设置列表视图进入“无”的SelectionMode。
上述正确的链接解释说,ListViewItem的“燕子”窃听事件的ListView如果设置为除“无”选择模式的权利。 我怎么能覆盖这个行为,让列表视图项被选中和列表视图仍是起火的RightTapped事件,我可以反应呢?
我相信我通过继承这两个ListView和ListViewItem的类解决了这个问题。
public class MyListView : ListView
{
protected override DependencyObject GetContainerForItemOverride()
{
return new MyListViewItem();
}
}
public class MyListViewItem : ListViewItem
{
protected override void OnRightTapped(Windows.UI.Xaml.Input.RightTappedRoutedEventArgs e)
{
base.OnRightTapped(e);
e.Handled = false; // Stop 'swallowing' the event
}
}
<CustomControls:MyListView
x:Name="MyListView"
...
SelectionMode="Single"
RightTapped="MyListView_RightTapped">
</CustomControls:MyListView>
通过这个简单的方法MyListView_RightTapped即使selectionMode是设置为“单”处理程序被调用,“多”或“扩展”。 但接下来的问题是这个小的胜利是否会导致应用程序UI的一个很好的设计。 我不打算在这里回答这个问题......
您可以使用在GridViewItem PointerPressed / PointerReleased事件,让你原本从RightTapped或在ManipulationCompleted获得同样的效果。
<ListView
Margin="120,80,0,0"
SelectionMode="Multiple">
<ListView.ItemContainerStyle>
<Style
TargetType="ListViewItem">
<Setter
Property="Width"
Value="100" />
<Setter
Property="Height"
Value="100" />
</Style>
</ListView.ItemContainerStyle>
<ListViewItem
RightTapped="ListViewItem_RightTapped_1"
PointerPressed="ListViewItem_PointerPressed_1"
PointerReleased="ListViewItem_PointerReleased_1"
ManipulationStarted="ListViewItem_ManipulationStarted_1">
<Rectangle
Height="80"
Width="80"
Fill="Red" />
</ListViewItem>
</ListView>
。
private void ListViewItem_RightTapped_1(object sender, RightTappedRoutedEventArgs e)
{
Debug.WriteLine("Tap");
}
private void ListViewItem_PointerPressed_1(object sender, PointerEventArgs e)
{
Debug.WriteLine("Press");
}
private void ListViewItem_ManipulationStarted_1(object sender, ManipulationStartedRoutedEventArgs e)
{
Debug.WriteLine("Manipulating");
}
private void ListViewItem_PointerReleased_1(object sender, PointerEventArgs e)
{
Debug.WriteLine("Release");
}
}
输出:
新闻稿新闻稿
*编辑
对不起,我必须以某种方式错过了它,这些事件与触摸和鼠标的工作方式不同。 我觉得你有可能是你会得到最好的答案。 否则 - 你需要实现自己的一个ListView的版本。 你可以尝试迫使他们希望得到在未来的版本中的一个更好的解决办法,但我不希望太多那里。 从我记得 - ContextMenus不是很地铁和有更好的解决方案UX比右键菜单。 您可以显示在AppBar或您选择一个项目后,打开一个详细信息页面上的命令。 这可能工作比试图破解的东西,从来没有设计为支持的解决方法更好。
我把@Jan泽曼的想法(upvoted,顺便说一句;)),并提高了一点。
的几个问题与原来的做法:
- 事件处理程序必须设置
e.Handled = true
,否则该事件将冒泡,直到Page
本身处理右抽头事件-并因此打开应用程序栏。 - 如果没有人听此事件,那么该事件将永远冒泡和到达
Page
。 - 当右抽头一个列表的项目或对周边的项目的空白发生的事件处理程序将被解雇。
这种方法解决上述问题:
public class MyListView : ListView
{
public event RightTappedEventHandler ItemRightTapped;
protected override DependencyObject GetContainerForItemOverride()
{
var item = new MyListViewItem();
item.RightTapped += OnItemRightTapped;
return item;
}
protected virtual void OnItemRightTapped(object sender, RightTappedRoutedEventArgs args)
{
if (ItemRightTapped != null)
ItemRightTapped(sender, args);
args.Handled = true;
}
}
public class MyListViewItem : ListViewItem
{
protected override void OnRightTapped(RightTappedRoutedEventArgs e)
{
base.OnRightTapped(e);
// Stop 'swallowing' the event
e.Handled = false;
}
}
现在,您可以订阅ItemRightTapped
事件相反,当且仅当一个项目是正确的挖掘,这将被触发。
该项目将标志着事件作为未处理,该列表将让你处理事件,然后将其标记为已处理-防止其向上冒泡,打的Page
。
文章来源: RightTapped not fired on Metro ListViewItem if ListView in other than “None” selection mode