【问题标题】:UWP: how to get the RightTapped GridView ItemUWP:如何获取 RightTapped GridView 项
【发布时间】:2017-05-02 22:27:34
【问题描述】:

我有一个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。

【问题讨论】:

    标签: c# wpf uwp


    【解决方案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);
    }
    

    【讨论】:

    • 谢谢mm8!您的解决方案对我来说效果很好,对于其他情况更通用。但我只能选择一个答案,另一个答案var student = (e.OriginalSource as FrameworkElement)?.DataContext as Student; 对我的情况很简短。所以我选择了另一个,同样感谢!
    • @BingLu mm8 的回答比我大。但是当DataTemplate 是TextBlock 时,它可能不会按预期使用。
    【解决方案2】:

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

    我的模型有一个类Student

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

    我的视图模型有一个List&lt;Student&gt;

    我将列表设置为 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。但如果您的 DataTemplate 是 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

    【讨论】:

    • 谢谢,var student = (e.OriginalSource as FrameworkElement)?.DataContext as Student; 为我工作。你说 OriginalSource 在我的例子中是ListViewItemPresenter。为什么不是GridViewItemPresenter
    猜你喜欢
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多