You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Xamarin.Forms中创建带多按钮卡片列表并获取项ID的技术问询

解决CollectionView卡片点击获取项ID的问题

我想创建如图所示的卡片列表,支持多个点击事件并能获取对应卡片的项ID,找过开源代码和NuGet包但没解决。用CollectionView时,没法获取卡片对应的项ID,给Label设x:Name也没用。附上我的XAML代码:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage.Resources>

<converters:ByteArrayToImageSourceConverter x:Key="ByteArrayToImage" />

</ContentPage.Resources>
<ContentPage.Content>

<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>

<Image.GestureRecognizers HeightRequest="30" WidthRequest="30">
</Image.GestureRecognizers>

            <CollectionView ItemsSource="{Binding Items}">
                <CollectionView.ItemsLayout>
                    <LinearItemsLayout Orientation="Horizontal" />
                </CollectionView.ItemsLayout>
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout Padding="0" Margin="2">
                            <Grid>
                                <StackLayout Padding="0" Margin="5,25,10,0" HorizontalOptions="Center">
                                    <Frame  BackgroundColor="White" HeightRequest="440" WidthRequest="330" HasShadow="True" Padding="5" Margin="0">
                                        <StackLayout>
                                            <Label x:Name="lblMessage" HorizontalOptions="StartAndExpand" Text="Rep:" IsVisible="false"></Label>

                                            <StackLayout HeightRequest="100" WidthRequest="320" Orientation="Horizontal" HorizontalOptions="Fill">
                                                <Frame HeightRequest="100" WidthRequest="320" BackgroundColor="Transparent" Padding="0" Margin="0">
                                                    <ImageButton Source="{Binding ImagemVideo, Converter={StaticResource ByteArrayToImage}}" Aspect="AspectFill"  Margin="0" Clicked="Video_Clicked"/>
                                                </Frame>

                                            </StackLayout>
                                            <Frame BorderColor="Transparent"  BackgroundColor="White"  HorizontalOptions="CenterAndExpand">
                                                <Label Grid.Column="0"                                    
                                               TextColor="#000000"
                                               Text="{Binding NomeTreino}"
                                               FontAttributes="None"
                                               HorizontalOptions="FillAndExpand"
                                               HorizontalTextAlignment="Start"
                                               Margin="8,0,10,10"
                                               FontSize="Medium"/>
                                            </Frame>
                                            <Frame BorderColor="LightGray" BackgroundColor="White"  HorizontalOptions="StartAndExpand">
                                                <Label Grid.Row="2" HorizontalOptions="StartAndExpand" Text="{Binding Descricao}"/>
                                            </Frame>

                                            <StackLayout Padding="0" Margin="5,5">
                                                <Grid Visual="Material">
                                                    <Grid.ColumnDefinitions>
                                                        <ColumnDefinition Width="*"/>
                                                        <ColumnDefinition Width="*"/>
                                                    </Grid.ColumnDefinitions>
                                                    <Grid.RowDefinitions>
                                                        <RowDefinition Height="65"/>
                                                        <RowDefinition Height="65"/>
                                                    </Grid.RowDefinitions>

                                                    <Frame Grid.Row="0" Visual="Material" Grid.Column="0" BorderColor="LightGray">
                                                        <StackLayout >
                                                            <Label HorizontalOptions="StartAndExpand" Text="Carga:"></Label>
                                                            <Label HorizontalOptions="CenterAndExpand"  Text="{Binding cargaInicial}"></Label>
                                                        </StackLayout>
                                                    </Frame>

                                                    <Frame Grid.Row="0" Grid.Column="1" BorderColor="LightGray">
                                                        <StackLayout >
                                                            <Label HorizontalOptions="StartAndExpand" Text="Séries:"></Label>
                                                            <Label   HorizontalOptions="CenterAndExpand" Text="{Binding serie1}"></Label>
                                                        </StackLayout>
                                                    </Frame>

                                                    <Frame Grid.Row="0" Grid.Column="2" BorderColor="LightGray">
                                                        <StackLayout >
                                                            <Label HorizontalOptions="StartAndExpand" Text="Rep:"></Label>
                                                            <Label  HorizontalOptions="CenterAndExpand" Text="{Binding repeticao1}"></Label>
                                                        </StackLayout>
                                                    </Frame>

                                                    <Frame Grid.Row="1" Grid.Column="0" BorderColor="LightGray">
                                                        <StackLayout >
                                                            <Label Text="{Binding tempoIntervalo}" ></Label>
                                                        </StackLayout>
                                                    </Frame>

                                                    <Frame Grid.Row="1" Grid.Column="2" BorderColor="LightGray">
                                                        <StackLayout >
                                                            <ImageButton  BackgroundColor="White" Source="Checkblue.png" Aspect="Fill"  HeightRequest="20" WidthRequest="20"  Margin="0" Clicked="BtnCheck_Clicked"/>
                                                        </StackLayout>
                                                    </Frame>

                                                </Grid>
                                            </StackLayout>
                                        </StackLayout>
                                    </Frame>
                                </StackLayout>
                            </Grid>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </ScrollView>
    </StackLayout>
</ContentPage.Content>

示例卡片


解决方案

方法1:在Clicked事件中直接获取绑定项

每个点击控件的Clicked事件里,可通过BindingContext拿到当前绑定的数据项,进而提取ID:

后台代码示例:

private void Video_Clicked(object sender, EventArgs e)
{
    // 替换成你实际的数据模型类
    var currentItem = (TrainingItem)((ImageButton)sender).BindingContext;
    int itemId = currentItem.Id;
    // 这里编写视频按钮的点击逻辑
}

private void BtnCheck_Clicked(object sender, EventArgs e)
{
    var currentItem = (TrainingItem)((ImageButton)sender).BindingContext;
    int itemId = currentItem.Id;
    // 这里编写勾选按钮的点击逻辑
}

注意:要确保你的数据模型类(比如TrainingItem)包含用于标识的ID属性。

方法2:用MVVM模式绑定Command(推荐)

如果采用MVVM架构,建议给按钮绑定Command和CommandParameter,直接把当前项作为参数传递:

修改XAML中的按钮代码:

<!-- 视频按钮 -->
<ImageButton Source="{Binding ImagemVideo, Converter={StaticResource ByteArrayToImage}}" 
             Aspect="AspectFill"  
             Margin="0" 
             Command="{Binding BindingContext.VideoCommand, Source={x:Reference Name=MainPage}}"
             CommandParameter="{Binding .}"/>

<!-- 勾选按钮 -->
<ImageButton BackgroundColor="White" 
             Source="Checkblue.png" 
             Aspect="Fill"  
             HeightRequest="20" 
             WidthRequest="20"  
             Margin="0" 
             Command="{Binding BindingContext.CheckCommand, Source={x:Reference Name=MainPage}}"
             CommandParameter="{Binding .}"/>

同时给你的ContentPage设置x:Name="MainPage",然后在ViewModel中定义命令:

public ICommand VideoCommand { get; }
public ICommand CheckCommand { get; }

public YourViewModel()
{
    VideoCommand = new Command<TrainingItem>(ExecuteVideoCommand);
    CheckCommand = new Command<TrainingItem>(ExecuteCheckCommand);
}

private void ExecuteVideoCommand(TrainingItem item)
{
    int itemId = item.Id;
    // 处理视频点击逻辑
}

private void ExecuteCheckCommand(TrainingItem item)
{
    int itemId = item.Id;
    // 处理勾选逻辑
}

关键说明

  • DataTemplate里的控件属于模板实例,通过x:Name直接访问后台会失效,这是设计特性,不要用这种方式拿数据。
  • 不需要额外的NuGet包或开源代码,用Xamarin.Forms自带的CollectionView和绑定机制就能解决问题。

内容的提问来源于stack exchange,提问作者Wesley Henrique dos Santos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:25:22