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

.NET MAUI中能否用ObservableCollection绑定数组动态显示收据商品项?

.NET MAUI 动态显示收据商品项数组(无需索引绑定)

我是.NET MAUI新手开发者,通过API的GET请求获取收据数据,每个收据包含数量不定的商品项,这些商品项存储在数组中。想了解能否不通过索引绑定,动态显示该数组?

我尝试的无索引绑定代码:

<Label Text="{Binding ReceiptPosition[].ModelNumber}" Grid.Column="5" Grid.Row="0" Margin="5,0,0,0"/>
<Label Text="{Binding ReceiptPosition[].ModelDescription}" Grid.Column="6" Grid.Row="0" Margin="5,0,0,0"/>
<Label Text="{Binding ReceiptPosition[].Quantity}" Grid.Column="7" Grid.Row="0" Margin="5,0,0,0"/>
<Label Text="{Binding ReceiptPosition[].SellingPrice}" Grid.Column="7" Grid.Row="0" Margin="5,0,0,0"/>

我的ViewModel:

internal partial class BelegPageViewModel : ObservableObject
{
    [ObservableProperty]
    ObservableCollection<BelegStruktur> belegeCollection = new();

    [ObservableProperty]
    private BelegStruktur beleg;
}

我的数据结构:

internal class BelegStruktur
{
    public DateTime? Date { get; set; }
    public int StoreNumber { get; set; }
    public int PointOfSaleNumber { get; set; }
    public int ReceiptNumber { get; set; }
    public ReceiptPosition[]? ReceiptPosition { get; set; }
}

public class ReceiptPosition
{
    public string ModelNumber { get; set; }
    public string ModelDescription { get; set; }
    public float Quantity { get; set; }
    public float SellingPrice { get; set; }
}

解决方案

你不能用ReceiptPosition[]这种数组直接通过无索引绑定遍历显示,需要借助.NET MAUI的集合控件(比如CollectionView)动态渲染集合中的每一项,同时建议将数组替换为ObservableCollection以支持UI自动更新。

1. 修改数据结构

把ReceiptPosition数组改成ObservableCollection,同时避免属性名和类名重复,重命名为ReceiptPositions:

internal class BelegStruktur
{
    public DateTime? Date { get; set; }
    public int StoreNumber { get; set; }
    public int PointOfSaleNumber { get; set; }
    public int ReceiptNumber { get; set; }
    // 替换数组为ObservableCollection,支持UI更新
    public ObservableCollection<ReceiptPosition>? ReceiptPositions { get; set; }
}

public class ReceiptPosition
{
    // 初始化避免空引用异常
    public string ModelNumber { get; set; } = string.Empty;
    public string ModelDescription { get; set; } = string.Empty;
    public float Quantity { get; set; }
    public float SellingPrice { get; set; }
}

2. 转换API返回的数组

从API获取数据后,将原始数组转换为ObservableCollection:

// 假设apiResponse是从接口获取的BelegStruktur对象
var apiResponse = await GetReceiptDataFromApi();
// 将数组转为ObservableCollection
apiResponse.ReceiptPositions = new ObservableCollection<ReceiptPosition>(apiResponse.ReceiptPosition ?? Array.Empty<ReceiptPosition>());

// 赋值给ViewModel的属性
Beleg = apiResponse;
// 或者添加到集合
BelegeCollection.Add(apiResponse);

3. XAML中用CollectionView动态显示

如果是显示单个收据的商品项:

<!-- 页面DataContext绑定到BelegPageViewModel -->
<CollectionView ItemsSource="{Binding Beleg.ReceiptPositions}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <!-- 用Grid布局每个商品项的字段 -->
            <Grid ColumnDefinitions="200,*,80,80" Margin="0,5">
                <Label Text="{Binding ModelNumber}" Grid.Column="0" Margin="5"/>
                <Label Text="{Binding ModelDescription}" Grid.Column="1" Margin="5"/>
                <Label Text="{Binding Quantity}" Grid.Column="2" Margin="5" HorizontalTextAlignment="End"/>
                <Label Text="{Binding SellingPrice, StringFormat='{0:C}'}" Grid.Column="3" Margin="5" HorizontalTextAlignment="End"/>
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

如果是显示多个收据的列表(嵌套CollectionView):

<CollectionView ItemsSource="{Binding BelegeCollection}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <VerticalStackLayout Margin="0,10">
                <!-- 显示收据头部信息 -->
                <Label Text="{Binding Date, StringFormat='日期: {0:yyyy-MM-dd}'}" FontSize="Medium" FontAttributes="Bold"/>
                <Label Text="{Binding StoreNumber, StringFormat='门店号: {0}'}"/>
                <Label Text="{Binding ReceiptNumber, StringFormat='收据号: {0}'}"/>
                
                <!-- 嵌套显示当前收据的商品项 -->
                <CollectionView ItemsSource="{Binding ReceiptPositions}" Margin="10,5">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <Grid ColumnDefinitions="200,*,80,80" Margin="0,3">
                                <Label Text="{Binding ModelNumber}" Grid.Column="0"/>
                                <Label Text="{Binding ModelDescription}" Grid.Column="1"/>
                                <Label Text="{Binding Quantity}" Grid.Column="2" HorizontalTextAlignment="End"/>
                                <Label Text="{Binding SellingPrice, StringFormat='{0:C}'}" Grid.Column="3" HorizontalTextAlignment="End"/>
                            </Grid>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </VerticalStackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

内容的提问来源于stack exchange,提问作者HeisenbergsMeth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:09:53