问题
I have a GridView
like below
<GridView
SelectionMode="None"
IsItemClickEnabled="True"
IsRightTapEnabled="True"
ItemsSource="{x:Bind SymbolItems}"
ItemClick="SymbolGridView_ItemClick"
RightTapped="SymbolGridView_RightTapped">
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:SoundSymbolItem">
<local:SymbolControl/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I have a ItemClick
handler and I can get the clicked symbolItem
successfully
private void SymbolGridView_ItemClick(object sender, ItemClickEventArgs e)
{
var symbolItem = (SymbolItem)e.ClickedItem;
MyMediaElement.Source = new Uri(this.BaseUri, symbolItem.SymbolAudio);
}
Now, I want to do the similar thing for the RightTapped
event, but it can't get the right tapped item.
private void SymbolGridView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
SymbolItem symbolItem = (sender as GridViewItem).DataContext as SymbolItem;
MyMediaElement.Source = new Uri(this.BaseUri, symbolItem.ExampleAudio);
}
I model the answer in this question Get RightTapped GridViewItem to write my right tapped handler above, but it's not working. When I right click a gridview item, a NullReferenceException is triggered.
回答1:
You should set SelectionMode="Single"
in gridview and set IsRightTapEnabled="True"
.
My model has a class Student
:
public class Student : NotifyProperty
{
public string Name
{
set
{
_name = value;
OnPropertyChanged();
}
get
{
return _name;
}
}
private string _name;
}
And my viewmodel has a List<Student>
.
I set the list as gridview's source.
My gridview is
<GridView x:Name="SymbolGridView"
SelectionMode="Single"
IsItemClickEnabled="True"
IsRightTapEnabled="True"
ItemsSource="{x:Bind View.Student}"
ItemClick="SymbolGridView_OnItemClick"
RightTapped="SymbolGridView_OnRightTapped">
<GridView.ItemTemplate>
<DataTemplate x:DataType="view:ViewModel">
<TextBlock Text="{Binding Name}"></TextBlock>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The SymbolGridView_OnRightTapped
have a OriginalSource that is TextBlock.But if your DataTemlpate is a Grid ,the OriginalSource is Grid.
We can use var student = (e.OriginalSource as TextBlock)?.DataContext as Student;
to get the student.
The OriginalSource.DataContext is your selects item
But if you use the Grid,the OriginalSource may is ListViewItemPresenter.So the easy methor is use var student = (e.OriginalSource as FrameworkElement)?.DataContext as Student;
See: http://lindexi.oschina.io/lindexi/post/win10-uwp-%E5%8F%B3%E5%87%BB%E9%80%89%E6%8B%A9GridViewItem
回答2:
If the SymbolControl in your ItemTemplate is a bit more complex and the elements in it may have their own DataContexts you could get a reference to the parent ListViewItemPresenter using the following helper method and then cast the DataContext of this to your Symbol item:
private void SymbolGridView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
ListViewItemPresenter lvi = e.OriginalSource as ListViewItemPresenter;
if (lvi == null)
lvi = FindParent<ListViewItemPresenter>(e.OriginalSource as DependencyObject);
if (lvi != null)
{
SymbolItem clickedItem = lvi.DataContext as SymbolItem;
if (clickedItem != null)
MyMediaElement.Source = new Uri(this.BaseUri, symbolItem.ExampleAudio);
}
}
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);
}
来源:https://stackoverflow.com/questions/41196009/uwp-how-to-get-the-righttapped-gridview-item