首页 > 解决方案 > 如何使用 TapGestureRecognizer 在列表视图中获取选定项

问题描述

我正在运行一个包含两列的 ListView,并且在每一列中放置一个 offert 对象。我需要知道用户是否点击了右侧或左侧的offert,但我还没有找到方法。

使用 selectedItem listview 事件时,我只能知道用户选择的列表视图中的行,但我不知道用户是单击右侧还是左侧提供。

<ListView SeparatorVisibility="None"  HasUnevenRows="True" SelectionMode="Single" ItemSelected="OnSelectItem" x:Name="listView">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell >
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="0"/>
                        <ColumnDefinition Width="*"/>
                    </Grid.ColumnDefinitions>

                    <Frame  IsVisible="{Binding IsVisible}" BindingContext="{Binding Item1}" Padding="1" BackgroundColor="#31b0d5" HasShadow="True" OutlineColor="#bbb">
                        <Grid  x:Name="GridItem1">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="100"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
                            <Frame BackgroundColor="White" Padding="5" HasShadow="False">
                                <Image Source="{Binding PhotoUrl}"  Aspect="AspectFill" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="80"/>
                            </Frame>
                            <StackLayout Grid.Row="1" Padding="5,0,5,5" Spacing="1">
                                <Label Text="{Binding name}" VerticalOptions="Center" HorizontalOptions="Center" FontSize="16" LineBreakMode="TailTruncation" TextColor="White" FontAttributes="Bold"/>
                                <Label Text="{Binding price, StringFormat='{0:C2}.'}" HorizontalOptions="Center" VerticalOptions="Center" FontSize="12" LineBreakMode="TailTruncation" TextColor="White"/>
                                <Label Text="{Binding link}" FontSize="12" TextColor="White" HorizontalOptions="Center"  VerticalOptions="Center" LineBreakMode="TailTruncation"/>
                            </StackLayout>
                        </Grid>
                        <Frame.GestureRecognizers>
                            <TapGestureRecognizer CommandParameter="{Binding .}" Command="{Binding onClickItem1,Source={x:Reference GridItem1}}"/>
                        </Frame.GestureRecognizers>
                    </Frame>

                    <Frame Grid.Column="2" IsVisible="{Binding IsVisible}" BindingContext="{Binding Item2}" Padding="1" BackgroundColor="#31b0d5" HasShadow="True" OutlineColor="#bbb">
                        <Grid  x:Name="GridItem2">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="100"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <Frame BackgroundColor="White" Padding="5" HasShadow="False">
                                    <Image Source="{Binding PhotoUrl}" Aspect="AspectFill" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="80"/>
                                </Frame>
                                <StackLayout Grid.Row="1" Padding="5,0,5,5" Spacing="1">
                                    <Label Text="{Binding name}" VerticalOptions="Center" HorizontalOptions="Center" FontSize="16" LineBreakMode="TailTruncation" TextColor="White"  FontAttributes="Bold"/>
                                    <Label Text="{Binding price, StringFormat='{0:C2}.'}" HorizontalOptions="Center" VerticalOptions="Center" FontSize="12" LineBreakMode="TailTruncation" TextColor="White"/>
                                    <Label Text="{Binding link}" FontSize="12" TextColor="White" HorizontalOptions="Center"  VerticalOptions="Center" LineBreakMode="TailTruncation" x:Name="linkLabel"/>
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="100"/>
                                            <ColumnDefinition Width="*"/>
                                        </Grid.ColumnDefinitions>
                                    </Grid>
                                </StackLayout>
                            </Grid>
                            <Frame.GestureRecognizers>
                                <TapGestureRecognizer Tapped="onClickItem2" NumberOfTapsRequired="1"/>
                                <TapGestureRecognizer CommandParameter="{Binding .}"  Command="{Binding onClickItem2,Source={x:Reference GridItem2}}"/>
                            </Frame.GestureRecognizers>
                        </Frame>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

我尝试使用手势识别器来解决它,但我无法让它工作。

我的列表视图的 XAML 代码是下一个:

在 XAML.CS 中,我创建了下一个注册用户点击的方法:

async void onClickItem1(object sender, EventArgs e) {
    if (sender != null) {
        OffertPair ofertDetail = (OffertPair) sender;

        Navigation.InsertPageBefore(new OffertPage(ofertDetail.Item1, Util.PageMode.DETAIL.ToString(), userName), this);
        await Navigation.PopAsync();
    } else {
        await DisplayAlert("Alert", "Please select and offert to go detail", "OK");
    }
}

显然失败是因为发件人不是 OffertPair。我的期望是发件人成为一个网格,但这是一个框架,我不明白原因。

如何获得选定的行和选定的 Offert?

标签: listviewxamarinselecteditem

解决方案


使用BindingContext发件人的

Element e = (Element)sender;
OffertPair ofertDetail = (OffertPair) e.BindingContext;

推荐阅读