手势识别器在ListView内无法工作

7
我有一个如下的列表视图(ListView):
<ListView
        Grid.Row="0"
        Margin="0"
        x:Name="ItemsListView"
        ItemsSource="{Binding SourceItems}"
        VerticalOptions="FillAndExpand"
        HasUnevenRows="false"
        RefreshCommand="{Binding LoadItemsCommand}"
        IsPullToRefreshEnabled="true"
        IsRefreshing="{Binding IsBusy}"
        ItemSelected="OnItemSelected"
        IsVisible="{Binding ShowListView}"
        RowHeight="55">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid
                        Margin="15,0,0,0"
                        Padding="0"
                        RowSpacing="0"
                        ColumnSpacing="0">
                        <Grid.RowDefinitions>
                            <RowDefinition
                                Height="*" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition
                                Width="1*" />
                            <ColumnDefinition
                                Width="7*" />
                            <ColumnDefinition
                                Width="1*" />
                            <ColumnDefinition
                                Width="1*" />
                        </Grid.ColumnDefinitions>
                        <Image
                            VerticalOptions="CenterAndExpand"
                            HorizontalOptions="CenterAndExpand"
                            HeightRequest="35"
                            WidthRequest="35"
                            Grid.Row="0"
                            Grid.Column="0"
                            Aspect="AspectFit"
                            Source="{Binding Icon}">
                        </Image>
                        <StackLayout
                            VerticalOptions="CenterAndExpand"
                            Spacing="0"
                            CompressedLayout.IsHeadless="true"
                            Margin="15,0,0,0"
                            Grid.Row="0"
                            Grid.Column="1">
                            <Label
                                VerticalTextAlignment="Start"
                                Text="{Binding Name}"
                                FontAttributes="Bold"
                                LineBreakMode="NoWrap"
                                Style="{DynamicResource ListItemTextStyle}"
                                FontSize="16" />
                            <Label
                                VerticalTextAlignment="Start"
                                Text="{Binding Description}"
                                LineBreakMode="NoWrap"
                                Style="{DynamicResource ListItemDetailTextStyle}"
                                FontSize="13" />
                        </StackLayout>
                        <Image
                            Grid.Row="0"
                            Grid.Column="3"
                            HeightRequest="20"
                            WidthRequest="20"
                            VerticalOptions="CenterAndExpand"
                            HorizontalOptions="StartAndExpand"
                            Aspect="AspectFit"
                            Source="{Binding Icon}" />
                        <Image
                            BackgroundColor="Lime"
                            Grid.Row="0"
                            Grid.Column="2"
                            InputTransparent="false"
                            Margin="0,0,10,0"
                            HeightRequest="20"
                            WidthRequest="20"
                            VerticalOptions="CenterAndExpand"
                            HorizontalOptions="StartAndExpand"
                            Aspect="AspectFit"
                            Source="ic_two">
                            <Image.GestureRecognizers>
                                <TapGestureRecognizer
                                    Command="{Binding OnFavouriteCommand}"
                                    CommandParameter="{Binding .}"
                                    NumberOfTapsRequired="1">
                                </TapGestureRecognizer>
                            </Image.GestureRecognizers>
                        </Image>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

在我的ViewModel中,我有

public ICommand OnFavouriteCommand { get; set; }

public MyViewModel()
{           
  OnFavouriteCommand = new Command<Object>(OnFavourite);
}

void OnFavourite(Object ob)
{
  Debug.WriteLine(ob);
}

我在 OnFavourite 上没有遇到断点。我不知道我错过了什么?我的想法是将手势识别器附加到每个图像上,并仅传递到该行绑定的项。

我刚刚注意到,如果我移动

<Image
            BackgroundColor="Lime"
            Grid.Row="1"
            InputTransparent="false"
            Margin="0,0,10,0"
            HeightRequest="20"
            WidthRequest="20"
            VerticalOptions="CenterAndExpand"
            HorizontalOptions="StartAndExpand"
            Aspect="AspectFit"
            Source="ic_favourites">
            <Image.GestureRecognizers>
                <TapGestureRecognizer
                    Command="{Binding OnFavouriteCommand}"
                    CommandParameter="{Binding .}"
                    NumberOfTapsRequired="1">
                </TapGestureRecognizer>
            </Image.GestureRecognizers>
        </Image>

ListView之外,断点确实会被触发!让我感到困惑... :|

2个回答

7
虽然Adit所写的是正确的,但让我给你一些背景知识。在DataTemplate中,单元格(以及它们的子元素)的BindingContext未设置为父级的BindingContext(即ListView),而是针对您的ListView.ItemSource中的每个元素创建一个单元格,并将其BindingContext设置为该元素。否则,您将无法将ViewCell的子元素的属性绑定到像Icon、Name、Description等字段。请保留HTML标签。
在WPF中,有可能绑定到父级的DataContext(请参见此处),但据我所知,在Xamarin.Forms中这是不可能的(请参见此处)。因此,您必须显式地引用父级,即通过x:Name="Page"(或任何您想要的名称)指定一个名称,然后通过绑定中的Source属性引用它。
Command="{Binding Path=BindingContext.OnFavouriteCommand,Source={x:Reference Page}}"

由于您将绑定源设置为Page而不是BindingContext,因此您需要将BindingContext添加到路径中。此外,为了将当前单元格所代表的元素传递给命令,您需要设置。
CommandParameter="{Binding .}"

CommandParameter绑定到由单元格引用的元素(您已经完成了此操作)。

嘿,保罗。谢谢你的背景介绍。我最终扩展了模型并添加了一个命令属性。 - envyM6

6
要在列表视图中使用手势,可以按照以下方式进行操作:
<Image
    BackgroundColor="Lime"
    Grid.Row="1"
    InputTransparent="false"
    Margin="0,0,10,0"
    HeightRequest="20"
    WidthRequest="20"
    VerticalOptions="CenterAndExpand"
    HorizontalOptions="StartAndExpand"
    Aspect="AspectFit"
    Source="ic_favourites">
    <Image.GestureRecognizers>
        <TapGestureRecognizer
            Command="{Binding Binding Path=BindingContext.OnFavouriteCommand,Source={x:Reference root}}"
            CommandParameter="{Binding .}"
            NumberOfTapsRequired="1">
        </TapGestureRecognizer>
    </Image.GestureRecognizers>
</Image>

在这里,根将是页面名称,例如设置X:您的页面名称为root,如x:Name="root"


谢谢Adit,我扩展了模型并添加了一个Command属性。 - envyM6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接