如何将多个控件绑定到 .NET maui 中的单个数据源?

问题描述 投票:0回答:1

我正在开发一个项目,它类似于在 maui 社区工具包的帮助下使用 MVVM 方案的购物车。我有一个可观察集合中的项目列表,点击/单击它们后,我将它们添加到一个单独的可观察集合中,我们将其称为购物车。对于购物车中的每个商品,我想显示商品的名称和商品的数量。默认情况下,它设置为 1,并且显示金额并限制为一个条目。我还有一个步进器控件,它的值也限制为该金额值,这样用户如果只想增加几个,则不必键入,如果他们想添加,也不必单击太多次喜欢 20 个项目。这一切都在此代码片段中完成:

<CollectionView
    Grid.Column="0"
    ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:InvoiceViewModel}}, Path=ItemsSold}">
                        <CollectionView.ItemTemplate>
                            <DataTemplate x:DataType="model:ItemSold">
                                <Grid
                                    ColumnDefinitions="*,*,80">
                                    <Label
                                        HorizontalOptions="Start"
                                        VerticalOptions="Center"
                                        Grid.Column="0"
                                        Style="{StaticResource DefaultLabelStyle}"
                                        Text="{Binding name}"/>
                                    <Entry
                                        HorizontalOptions="Start"
                                        VerticalOptions="Center"
                                        WidthRequest="150"
                                        Grid.Column="1"
                                        BackgroundColor="White"
                                        Text="{Binding amount}"/>
                                    <Stepper
                                        Grid.Column="2"
                                        Value="{Binding amount}"
                                        Increment="1"
                                        Minimum="0"
                                        Maximum="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:InvoiceViewModel}}, Path=inf}"/>
                                </Grid>
                            </DataTemplate>
                        </CollectionView.ItemTemplate>
</CollectionView>

我有一个按钮,单击该按钮会显示该项目的数量,以便我可以调试一些代码。当我在条目中键入一个值(例如 5)并单击按钮时,它显示金额为 5。如果我单击步进器中的增加按钮并单击按钮,它显示 2,默认值 1 + 1,从中我看到有是 amount 变量的两个实例,这不是我想要的。我希望输入控件和步进控件能够同时相互更新,同时也更新绑定数据。 在我的视图模型中,这就是我所拥有的:

public ObservableCollection<Item> Items { get; set; } = new();
public ObservableCollection<ItemSold> ItemsSold { get; set; } = new();
public int inf = int.MaxValue;

public InvoiceViewModel() { }

public async Task GetItems()
{
    await InventoryService.Init();
    try
    {
        var items = await InventoryService.GetItems();
        if (Items.Count != 0) { Items.Clear(); }
        foreach (var item in items)
        {
            Items.Add(item);
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
        await Shell.Current.DisplayAlert("Error", "Unable to fetch inventory \n" + ex.Message, "OK");
    }
}

[RelayCommand]
private void AddToInvoice(Item item)
{
    if (item.unitPrice is null) { return; }
    ItemSold itemSold = new();
    itemSold.name = item.name;
    itemSold.description = item.description;
    itemSold.unitName = item.unitName;
    itemSold.unitPrice = (double)item.unitPrice;
    itemSold.amount = 1;
    ItemsSold.Add(itemSold);
}
        

我尝试过将双向绑定模式添加到仅条目、仅步进器以及两者,但都没有解决问题。由于在手势点击完成之前条目和步进器不存在,因此我无法在视图模型中创建属性并使用 maui 社区工具包中的可观察属性标签对其进行标记。将金额数据绑定到条目和步进器以便它们始终共享相同的值时,我缺少什么?

c# data-binding maui
1个回答
0
投票

您可以使用 MVVM Toolkit 来实现这一点。

您可以尝试为 public int amount 添加

ObservableProperty
属性(
ItemSold.cs
)。然后它会生成一个可观察的属性
Amount
。 如果更改
Amount
的值,UI 将自行更新(包括
Entry
Stepper
)。

public partial class ItemSold:ObservableObject
{
    public string name { get; set; }

    [ObservableProperty]
    public int amount;
}

然后在

InvoiceViewModel.cs
中,我为
ItemsSold
添加了一些假数据。

public partial class InvoiceViewModel: ObservableObject
    {

        public ObservableCollection<ItemSold> ItemsSold { get; set; } = new ObservableCollection<ItemSold>();

        public int inf = int.MaxValue;

        public ICommand GetCommand { get; set; }

        public InvoiceViewModel() {

            ItemsSold.Add(new ItemSold { name ="Name 1",Amount = 1});
            ItemsSold.Add(new ItemSold { name ="Name 2", Amount = 1});
            ItemsSold.Add(new ItemSold { name ="Name 3", Amount = 1});
        }

        [RelayCommand]
        private void GetResult()
        {
           foreach (var item in ItemsSold)
            {
                System.Diagnostics.Debug.WriteLine("------- item's name is: " + item.name +"<---> count is : " + item.Amount);

            }
        }

    }

最后,我们需要为Entry和

Amount
绑定生成的属性
Stepper
。 例如:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiCheckListviewApp.Views.SharedNumberPage"
             xmlns:viewmodel ="clr-namespace:MauiCheckListviewApp.ViewModes"
             xmlns:model ="clr-namespace:MauiCheckListviewApp.Models"
             Title="SharedNumberPage">

    <ContentPage.BindingContext>
        <viewmodel:InvoiceViewModel></viewmodel:InvoiceViewModel>
    </ContentPage.BindingContext>
    <VerticalStackLayout>
        <CollectionView  Grid.Column="0" ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:InvoiceViewModel}}, Path=ItemsSold}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="model:ItemSold">
                    <Grid
                                    ColumnDefinitions="*,*,80">
                        <Label
                                        HorizontalOptions="Start"
                                        VerticalOptions="Center"
                                        Grid.Column="0"
                                        Text="{Binding name}"/>
                        <Entry
                                        HorizontalOptions="Start"
                                        VerticalOptions="Center"
                                        WidthRequest="150"
                                        Grid.Column="1"
                                        BackgroundColor="White"
                                        Text="{Binding Amount}"/>
                        <Stepper
                                        Grid.Column="2"
                                        Value="{Binding Amount}"
                                        Increment="1"
                                        Minimum="0"
                                        Maximum="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:InvoiceViewModel}}, Path=inf}"/>
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

        <Button  Text="get result" Command="{Binding GetResultCommand}"/>
    </VerticalStackLayout>
</ContentPage>

注:

我还添加了一个按钮来获取

ItemsSold
的最后结果来验证数字,结果也符合我们的预期:Entry和Stepper共享相同的数量。

© www.soinside.com 2019 - 2024. All rights reserved.