如果没有ListItem
事件和相关来源,有没有办法让RightTappedRoutedEventArgs e
来自SelectionChanged
,因为此ListView
有SelectionMode="none"
。如果使用SelectionMode="none"
无法做到这一点,是否可以使用其他选择类型,但仍然没有选择更改事件?
下面的项目xaml模板。
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="56" Width="300">
<Image .../>
<TextBlock .../>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
由于一些实验,我已经将ListView(具有当前未使用的功能)子类化,并且还使用RightTapped子类化了ListViewItem。也许有办法将this
附加到活动中?将此作为选择结果存储在子类ListView中是一种不好的行为。
答案 0 :(得分:1)
我意识到这是一个老问题,但是本周我偶然发现了这个问题。
在很多情况下,Crea7or的回答是正确的(一旦您展示了DataContext,就可以经常使用ContainerFromItem
来获取ListViewItem
),但是它在两种重要情况下也不起作用:
ItemTemplate
包含其他具有自己的DataContext
s的元素,例如<Button>
(甚至是隐式的)。对于第一种情况(由键盘激活的 ),e.OriginalSource
没有DataContext。但是,e.OriginalSource
已经是ListViewItem
!这样就完成了!
但是,对于第二种情况(包含具有自己的DataContexts 的元素),查看DataContext可能会为您提供孩子的DataContext,而不是您想要的!
查找 ListViewItem 的最可靠的方法是简单地沿着树走(从mm8's answer改编为类似的问题):
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);
}
如果您确信第二种情况不适用,则可以采用一种更简单的方法来从任意事件中获取 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;
}
但是,此问题的原始答案实际上是想要获取实际对象支持 ListViewItem。
要可靠地找到要表示的实际对象-在处理上述所有其他情况时,请获取 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还有一些非常好的辅助方法,例如IndexFromContainer。
编辑历史记录:
答案 1 :(得分:0)
<ListView.ItemTemplate>
<DataTemplate>
<Grid Height="56" Width="300" IsHitTestVisible="False">
...
所以现在我始终将Border
视为原始发件人。之前是TextBox
或Image
。
然后在:
private void itemsListBoxRightTapped( object sender, RightTappedRoutedEventArgs e )
{
Border clickBorder = e.OriginalSource as Border;
if ( clickBorder != null )
{
MyItemType selectedItem = clickBorder.DataContext as MyItemType;
...
中提琴!点按项目。
现在正确完成了ListView的上下文菜单;)
更新:Windows通用应用有[{1}}而不是ListViewItemPresenter
。