[英]Detect ListViewitem where rightTapped event happened
Is there any way to get the ListItem
from RightTappedRoutedEventArgs e
without SelectionChanged
event and related sources because this ListView
have SelectionMode="none"
.有没有办法从
RightTappedRoutedEventArgs e
获取ListItem
而没有SelectionChanged
事件和相关来源,因为这个ListView
有SelectionMode="none"
。 If this is not possible with SelectionMode="none"
, will it be available with other selection types, but still without selection change event?如果使用
SelectionMode="none"
无法做到这一点,那么它是否适用于其他选择类型,但仍然没有选择更改事件?
Item xaml template below.下面的项目 xaml 模板。
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="56" Width="300">
<Image .../>
<TextBlock .../>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
Due to some experiments, I have subclassed ListView (with currently unused functionality) and also subclassed ListViewItem with handling RightTapped.由于一些实验,我已经将 ListView 子类化(具有当前未使用的功能),并且还使用处理 RightTapped 子类化了 ListViewItem。 Maybe there is any way to attach
this
to event?也许有什么办法可以连接
this
给事件? Storing this as selection result in subclassed ListView is a not good behavior I think.我认为将其作为选择结果存储在子类 ListView 中是一种不好的行为。
I realize this is an old question, but I stumbled upon it this week.我意识到这是一个老问题,但本周我偶然发现了它。
Crea7or's answer is correct in many cases (once you have the DataContext as they demonstrate, you can often use ContainerFromItem
to get the ListViewItem
), but it also does not work in two important scenarios: Crea7or 的答案在许多情况下是正确的(一旦您拥有了他们演示的 DataContext,您通常可以使用
ContainerFromItem
来获取ListViewItem
),但它在两个重要场景中也不起作用:
ItemTemplate
contains other elements with their own DataContext
s , like a <Button>
(even implicit).ItemTemplate
包含其他具有自己DataContext
的元素,例如<Button>
(甚至是隐式的)。 For the first scenario ( activated by keyboard ), e.OriginalSource
has no DataContext.对于第一个场景(由键盘激活),
e.OriginalSource
没有 DataContext。 However, e.OriginalSource
is already the ListViewItem
!但是,
e.OriginalSource
已经是ListViewItem
! So you're done!所以你完成了!
However, for the second scenario ( contains elements with their own DataContexts ), looking at the DataContext might get you a DataContext for a child—not what you want!但是,对于第二个场景(包含具有自己的 DataContext 的元素),查看 DataContext 可能会为您提供一个孩子的 DataContext——而不是您想要的!
The most robust way of looking up the ListViewItem is simply to walk up the tree (adapted from mm8's answer to a similar question):查找ListViewItem最健壮的方法是简单地沿着树走(改编自mm8对类似问题的回答):
private static T FindParent<T>(DependencyObject dependencyObject) where T : DependencyObject
{
var parent = VisualTreeHelper.GetParent(dependencyObject);
if (parent == null) return null;
var parentT = parent as T;
return parentT ?? FindParent<T>(parent);
}
// ... in your code ...
ListViewItem lvi = e.OriginalSource as ListViewItem;
if (lvi == null)
{
lvi = FindParent<ListViewItem>(e.OriginalSource as DependencyObject);
}
If you are confident that the second scenario does not apply, you can take a simpler approach to get the ListViewItem from an arbitrary event:如果您确信第二种情况不适用,则可以采用更简单的方法从任意事件中获取ListViewItem :
var listViewItem = e.OriginalSource as ListViewItem;
if (listViewItem == null)
{
var dataContext = (e.OriginalSource as FrameworkElement).DataContext;
listViewItem = (sender as ListView).ContainerFromItem(dataContext) as ListViewItem;
}
However, the original answer to this question actually wanted to grab the actual object backing the ListViewItem.然而,这个问题的原始答案实际上是想获取支持ListViewItem 的实际对象。
To find the actual object being represented robustly—while handling all the additional scenarios outlined above, fetch the ListViewItem and use the ItemsControl.ItemFromContainer
method to get the actual object:要找到可靠表示的实际对象——在处理上述所有附加场景的同时,获取ListViewItem并使用
ItemsControl.ItemFromContainer
方法来获取实际对象:
private void itemsListBoxRightTapped( object sender, RightTappedRoutedEventArgs e )
{
MyItemType item;
ListViewItem lvi = e.OriginalSource as ListViewItem;
if (listViewItem == null)
{
// Use earlier definition for FindParent.
listViewItem = FindParent<ListViewItem>(e.OriginalSource as DependencyObject);
}
item = (sender as ListView).ItemFromContainer(listViewItem) as MyItemType;
// We have the item!
}
ItemsControl has some other very nice helper methods, like IndexFromContainer . ItemsControl有一些其他非常好的辅助方法,例如IndexFromContainer 。
Edit history:编辑历史:
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="56" Width="300" IsHitTestVisible="False">
...
So now I see always Border
as original sender.所以现在我总是将
Border
视为原始发件人。 It was TextBox
or Image
before.之前是
TextBox
或Image
。
then at:然后在:
private void itemsListBoxRightTapped( object sender, RightTappedRoutedEventArgs e )
{
Border clickBorder = e.OriginalSource as Border;
if ( clickBorder != null )
{
MyItemType selectedItem = clickBorder.DataContext as MyItemType;
...
viola!中提琴! Tapped item.
点击的项目。
Now correct context menu for ListView is done ;)现在完成了 ListView 的正确上下文菜单;)
Update : Windows Universal apps have ListViewItemPresenter
instead of Border
.更新:Windows 通用应用程序具有
ListViewItemPresenter
而不是Border
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.