【问题标题】:Xamarin Forms - How to populate ListView from the data you entered?Xamarin Forms - 如何从您输入的数据中填充 ListView?
【发布时间】:2018-08-14 13:38:22
【问题描述】:

流程:

第 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>

QuantityPopUp.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# android xaml xamarin xamarin.forms


    【解决方案1】:

    您的问题很简单,但被您提供的大量代码所掩盖。下次您应该尝试将其归结为Minimal, Complete, and Verifiable example

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

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

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

    这与您的问题有何关系?

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

    var popup = new QuantityPopUp(_sender);
    

    因此创建了ObservableCollection&lt;CartOrderAdd&gt;new 实例,默认情况下为空。您会立即向其中添加餐点,然后单击 OK 即可进入结帐购物车。即使有其他餐点应该添加到您的购物车中,它们也会在某些列表中的内存中某处,但(当然)不在您新创建的列表中。

    你怎么能解决这个问题?

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

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

    请注意,仅传递了 mealCodequantity,因为不应由 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();
        }
    
        // ...
    }
    

    【讨论】:

    • @JeremyPaul 很高兴我能帮上忙。
    • Cart.Instance.Add(tempcodeofmenu, int.Parse(entQuantity.Text)); 顺便说一句,您从哪里获得“实例”
    • MyCart.ItemsSource = Cart.Instance.GetAddedMeals();GetAddedMeals() 是新的 ViewModel 吗?
    • Cart 是一个单例。您必须自己实现public static Cart Instance
    • 你能告诉我一些如何实现单例的例子吗?
    猜你喜欢
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 2020-05-06
    • 2015-09-14
    相关资源
    最近更新 更多