首页 > 解决方案 > Xamarin Forms - 如何从您输入的数据中填充 ListView?

问题描述

过程:

第 1 步:在食物菜单中,您可以选择您要订购的食物,如果您点击它会显示数量弹出窗口

OrdernowMenu.xaml 的图像

立即订购菜单

链接:https ://i.stack.imgur.com/qqPUD.jpg

OrdernowMenu.xaml

  <ContentPage.ToolbarItems>
        <ToolbarItem Icon="cartimage.png" Clicked="ToolbarItem_Clicked"></ToolbarItem>

    </ContentPage.ToolbarItems>

    <ListView x:Name="MyOrder" ItemSelected="MyOrder_ItemSelected" RowHeight="100">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <Grid ColumnSpacing="0" RowSpacing="0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <StackLayout Grid.Row="0" Grid.Column="0" >
                            <Image Source="{Binding menu_image ,StringFormat='https://i.imgur.com/{0:F0}.png'}"  Aspect="AspectFill"/>
                        </StackLayout>
                        <StackLayout Grid.Row="0" Grid.Column="1" VerticalOptions="Center">
                            <Label Text="{Binding menu_name}" Font="30"/>
                            <Label Text="{Binding menu_price,StringFormat='₱ {0:F0}'}" Font="20"/>
                            <Label Text="{Binding menu_availability} " Font="10" />
                        </StackLayout>
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

OrdernowMenu.xaml.cs

public partial class OrdernowMenu : ContentPage
    {
        public float totalprice { get; set; }
        public string json_response { get; set; }
        public string seletedMenu { get; set; }
        public string menuPrice { get; set; }
        public string quantity { get; set; }
        public string menucode { get; set; }


        public OrdernowMenu(PostSender posts1)
        {
            InitializeComponent();


            json_response = posts1.response;
            tester = posts1.teststring;
            GetUserAsync();
        }



        private async Task GetUserAsync()
        {

            var user = JsonConvert.DeserializeObject<List<Menus>>(json_response);

            MyOrder.ItemsSource = user;


        }



        public async Task MyOrder_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {

            var selectedOrder = e.SelectedItem as Menus;

            if (selectedOrder != null)

                seletedMenu = selectedOrder.menu_name;
            menuPrice = selectedOrder.menu_price;
            menucode = selectedOrder.menu_code;



            CartSender _sender = new CartSender()
            {
                nameofmenu = seletedMenu,
                priceofmenu = menuPrice,
                codeofmenu = menucode
            };

            var popup = new QuantityPopUp(_sender);
            await  Navigation.PushAsync(popup);

        }




        public void ToolbarItem_Clicked(object sender, EventArgs e)
        {



            Navigation.PushAsync(new OrderCart(null));


        }
    }

第 2 步:在此处输入订单数量,然后点击确定,它将被添加到订单列表/购物车

我的问题在这里:它只在OrderCart.xaml中显示我的最新订单,如果您有多个订单,它不会堆叠。

QuantityPopUp.xaml 的图像

数量弹出

链接:https ://i.stack.imgur.com/cvlB4.jpg

QuantityPopUp.xaml

<ContentPage.ToolbarItems>
        <ToolbarItem Name="Cancel" Clicked="Cancel_Clicked" ></ToolbarItem>

    </ContentPage.ToolbarItems>
    <StackLayout Orientation="Vertical" VerticalOptions="Center">

        <StackLayout Orientation="Vertical" HorizontalOptions="Center">
            <Label Text="Input Quantity" FontAttributes="Bold" Font="30"/>
            <Entry x:Name="entQuantity" Placeholder="How many do you want?" Keyboard="Numeric" HorizontalTextAlignment="Center"/>
        </StackLayout>
        <StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="Center">
            <Button x:Name="btnOK" Text="OK"  Clicked="btnOK_Clicked" />


        </StackLayout>
    </StackLayout>

数量PopUp.xaml.cs

public partial class QuantityPopUp : ContentPage
    {
        public string tempnameofmenu { get; set; }
        public string temppriceofmenu { get; set; }
        public string tempcodeofmenu { get; set; }
        public string tempquantityofmenu { get; set; }
        ObservableCollection<CartOrderAdd> test = new ObservableCollection<CartOrderAdd>();

        public QuantityPopUp (Data.CartSender _sender)
        {
            InitializeComponent();
            tempnameofmenu = _sender.nameofmenu;
            temppriceofmenu = _sender.priceofmenu;
            tempcodeofmenu = _sender.codeofmenu;

        }

        private void btnOK_Clicked(object sender, EventArgs e)
        {


            test.Add(new CartOrderAdd
            {
                nameofmenuCOA = tempnameofmenu,
                codeofmenuCOA = tempcodeofmenu,
                priceofmenuCOA = temppriceofmenu,
                quantityofmenuCOA = entQuantity.Text
            });


            var viewcart = new OrderCart(test);
            Navigation.PushAsync(viewcart);

        }



        private void Cancel_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new OrdernowCategory());
        }
    }

第 3 步:如果您转到 OrderCart.xaml,它必须显示您的所有订单。

我的问题在这里:我不知道出了什么问题,因为即使我有多个订单,它也只显示一个订单。

OrderCart.xaml 的图像

购物车

链接:https ://i.stack.imgur.com/qiiPP.jpg

OrderCart.xaml

 <ContentPage.ToolbarItems>
        <ToolbarItem Name="Back" Clicked="Back_Clicked" ></ToolbarItem>

    </ContentPage.ToolbarItems>

    <ListView x:Name="MyCart" ItemSelected="MyCart_ItemSelected"  RowHeight="50">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell >
                    <Grid>



                        <StackLayout Orientation="Horizontal">
                            <Label  Text="{Binding nameofmenuCOA}" Font="30" TextColor="Black" FontAttributes="Bold"/>
                            <Label  Text="{Binding priceofmenuCOA}" Font="30" TextColor="Black" FontAttributes="Bold"/>
                            <Label  Text="{Binding codeofmenuCOA}" Font="30" TextColor="Black" FontAttributes="Bold"/>
                            <Label  Text="{Binding quantityofmenuCOA}" Font="30" TextColor="Black" FontAttributes="Bold"/>
                        </StackLayout>


                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>

    </ListView>

OrderCart.xaml.cs

public partial class OrderCart : ContentPage
    {
        List<CartOrderAdd> _data;


        public OrderCart (System.Collections.ObjectModel.ObservableCollection<CartOrderAdd> test)
        {
            InitializeComponent ();


            MyCart.ItemsSource = test;
        }

        private void MyCart_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {

        }

        private void Back_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new OrdernowCategory());
        }
    }

标签: c#androidxamlxamarinxamarin.forms

解决方案


您的问题很简单,但被您提供的大量代码所遮挡。下次您应该尝试将其归结为最小、完整和可验证的示例

test集合是一个实例变量,这意味着将为包含类 ( QuantityPopUp) 的每个实例创建一个新变量。如果我创建了该类的多个实例

var a = new QuantityPopUp();
var b = new QuantityPopUp();
var c = new QuantityPopUp();

内存中会有三个区域,每个区域包含一个QuantityPopUp. 其中每一个都将包含一个指向包含 a的区域 im 内存的指针ObservableCollection<CartOrderAdd>(好吧,实际上它并不是那么简单,但这将作为一个简化的模型来理解这个问题)。每个ObservableCollection<CartOrderAdd>可能包含不同的值。

这与您的问题有什么关系?

现在,每当您单击列表中的项目时,您都在创建一个的类型实例QuantityPopUp

var popup = new QuantityPopUp(_sender);

因此创建了一个的实例,ObservableCollection<CartOrderAdd>默认情况下为空。您会立即向其中添加餐点,然后单击“确定” ,您将进入结帐购物车。即使有其他餐点应该添加到您的购物车中,它们也存在于某些列表中的内存中,但(当然)不在您新创建的列表中。

你怎么能解决这个问题?

我建议使用依赖注入的 MVVM 和像 Prism 这样的框架。您可以创建一个Cart注入到您的视图模型中的一个(请不要将添加的餐点保存在内存中或者应该只有一个实例Cart)。签名可能如下所示

class Cart
{
    public void AddOrder(string mealCode, int quantity);
    public IReadOnlyCollection<Meal> GetAddedMeals();
} 

请注意,只有 themealCode和 thequantity被通过,因为它不应该由 UI 来确定价格(这将是多余的、容易出错并可能为滥用打开大门)和菜单的名称(不如价格,但仍然)。

现在,如果您不想/不能将 MVVM 与 DI 一起使用,您可以使用该Cart对象。例如,通过在视图之间传递它或使用单例实现(我不建议您这样做,但您可以)。

您的视图背后的代码可能如下所示。

public partial class QuantityPopUp : ContentPage
{
    // ...

    private void btnOK_Clicked(object sender, EventArgs e)
    {
        Cart.Instance.Add(tempcodeofmenu, int.Parse(entQuantity.Text));

        Navigation.PushAsync(new OrderCart());
    }

    // ...
}

public partial class OrderCart : ContentPage
{
    public OrderCart()
    {
        InitializeComponent ();

        MyCart.ItemsSource = Cart.Instance.GetAddedMeals();
    }

    // ...
}

推荐阅读