首页 > 解决方案 > Xamarin Forms 在图像单击时获取对象元素

问题描述

我有个问题。我从一个名为的列表中创建了一个 CollectionView:List<Set> Sets并且在一个集合中我有一个名为 的列表List<Picture> Pictures

下面是这些类的样子:

public class Set
{
    public int Id { get; set; }
    public List<Picture> Pictures{ get; set; }
}

图片类如下所示:

public class Picture
{
    public int Id { get; set; }
    public string Name { get; set; }
}

现在在我的 XAML 中,我在每个图像上添加了一个点击事件,因为我需要知道哪个图像被点击了。问题是我还需要知道图像点击是在哪个集合中完成的,因为一个图像可以在多个集合中。

这是 XAML:

<CollectionView ItemsSource="{Binding Sets}">
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <ScrollView Orientation="Horizontal">
                <StackLayout BindableLayout.ItemsSource="{Binding Pictures}" Orientation="Horizontal">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <ff:CachedImage Aspect="AspectFill" Source="{Binding imageSource}">
                                <ff:CachedImage.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="AlbumFoto_Clicked" />
                                </ff:CachedImage.GestureRecognizers>
                            </ff:CachedImage>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </ScrollView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

现在我已经得到了这个代码:

private void AlbumFoto_Clicked(object sender, EventArgs e)
{
    CachedImage image = (CachedImage)sender;
    var setPicture = image.Source.BindingContext as Picture;
    var ImageId = setPicture.Id;

    var Pictureindex = 0;
    foreach (var set in Sets.Where(set => Pictures.Picture.Any(p => p.Id == ImageId)))
    {
        Pictureindex = set.Pictures.Picture.FindIndex(p => p.Id == ImageId);
    }
}

现在如何从一组点击的图像中获取 ID?

标签: c#xamarinxamarin.formsxamarin.androidxamarin.ios

解决方案


而不是使用单击事件,您应该使用CommandCommandParameter使用父集合的 BindingContext

<CollectionView ItemsSource="{Binding Sets}">
    <CollectionView.ItemsLayout>
        <GridItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <ScrollView x:Name="ParentCollection" Orientation="Horizontal">
                <StackLayout BindableLayout.ItemsSource="{Binding Pictures}" Orientation="Horizontal">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <ff:CachedImage Aspect="AspectFill" Source="{Binding imageSource}">
                                <ff:CachedImage.GestureRecognizers>
                                    <TapGestureRecognizer Command="{Binding ImageClickCommand}" CommandParameter="{Binding BindingContext.Id, Source={x:Reference Name=ParentCollection}}"/>
                                </ff:CachedImage.GestureRecognizers>
                             </ff:CachedImage>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>
            </ScrollView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

在您的 ViewModel 中:

public Command<int> ImageClickCommand{ get; set; }

在您的 ViewModel 构造函数中:

ImageClickCommand = new Command<int>((Id) =>
{
    //Id -> id of the image
});

但是,如果您仍想使用 Clicked 事件,我建议您进行此更改。

将新属性添加到您的图片类:

public class Picture
{
    public int Id { get; set; }
    public int SetId { get; set; }
    public string Name { get; set; }
}

假设您从服务接收到该集合,您可以对其进行迭代并像这样设置您的 SetId:

foreach (var item in Collection)
{
    foreach (var picture in item.Pictures)
    {
         picture.SetId = item.Id   
    }         
}

现在,在您的 Clicked 中,您应该可以同时访问 Picture Id 和相应的 Set Id:

private void AlbumFoto_Clicked(object sender, EventArgs e)
{
    CachedImage image = (CachedImage)sender;
    var setPicture = image.Source.BindingContext as Picture;
    var ImageId = setPicture.Id;
    var SetId = setPicture.SetId;
    //...
}

推荐阅读