UWP:如何获取RightTapped GridView项目

时间:2016-12-17 06:33:06

标签: c# wpf uwp

我有GridView,如下所示

<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>

我有一个ItemClick处理程序,我可以成功点击symbolItem

    private void SymbolGridView_ItemClick(object sender, ItemClickEventArgs e)
    {
        var symbolItem = (SymbolItem)e.ClickedItem;
        MyMediaElement.Source = new Uri(this.BaseUri, symbolItem.SymbolAudio);
    }

现在,我想为RightTapped事件做类似的事情,但它无法获得正确的点击项目。

    private void SymbolGridView_RightTapped(object sender, RightTappedRoutedEventArgs e)
    {
        SymbolItem symbolItem = (sender as GridViewItem).DataContext as SymbolItem;
        MyMediaElement.Source = new Uri(this.BaseUri, symbolItem.ExampleAudio);
    }

我在这个问题Get RightTapped GridViewItem中对答案进行了建模,以便在上面编写我的右侧点击处理程序,但它不起作用。当我右键单击gridview项时,会触发NullReferenceException。

2 个答案:

答案 0 :(得分:1)

如果ItemTemplate中的SymbolControl有点复杂,并且其中的元素可能有自己的DataContexts,您可以使用以下帮助器方法获取对父ListViewItemPresenter的引用,然后将此DataContext转换为Symbol项:

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

答案 1 :(得分:0)

您应该在gridview中设置SelectionMode="Single"并设置IsRightTapEnabled="True"

我的模型有一个班级Student

public class Student : NotifyProperty
{
    public string Name
    {
        set
        {
            _name = value;
            OnPropertyChanged();
        }
        get
        {
            return _name;
        }
    }

    private string _name;
}

我的viewmodel有List<Student>

我将列表设置为gridview的源。

我的gridview是

   <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>

SymbolGridView_OnRightTapped有一个OriginalSource是TextBlock.But,如果你的DataTemlpate是一个Grid,那么OriginalSource就是Grid。

我们可以使用var student = (e.OriginalSource as TextBlock)?.DataContext as Student;来吸引学生。

OriginalSource.DataContext是您的选择项

但是如果你使用Grid,那么OriginalSource可能是ListViewItemPresenter。所以简单的方法是使用var student = (e.OriginalSource as FrameworkElement)?.DataContext as Student;

请参阅:http://lindexi.oschina.io/lindexi/post/win10-uwp-%E5%8F%B3%E5%87%BB%E9%80%89%E6%8B%A9GridViewItem