Reputation: 72
Process:
Step 1: In Food menu you can select you want to order , if you tapped it quantity popup will show
image of OrdernowMenu.xaml
Link:https://i.sstatic.net/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));
}
}
Step 2: This where you input the quantity of your order, and you tap OK it will be added to the orderlist/Cart
My Problem here: it only display my latest order in OrderCart.xaml and it doesn't stack if you have multiple orders.
image of QuantityPopUp.xaml
Link:https://i.sstatic.net/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());
}
}
Step 3: if you go to OrderCart.xaml this must display all of your orders.
My Problem Here: i don't know what's wrong because it only display a single order even though i have multiple orders.
image of OrderCart.xaml
Link:https://i.sstatic.net/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());
}
}
Upvotes: 0
Views: 1790
Reputation: 9713
Your issue is quite simple, but occluded by the heaps of code you presented. The next time you should try to boil it down to a Minimal, Complete, and Verifiable example.
The test
collection is an instance variable, that means that a new variable will be created of each instance of the containing class (QuantityPopUp
). If I created multiple instances of the class
var a = new QuantityPopUp();
var b = new QuantityPopUp();
var c = new QuantityPopUp();
there would be three regions in memory, each containing a QuantityPopUp
. And each of these would contain a pointer to a region im memory containing a ObservableCollection<CartOrderAdd>
(alright, actually it's not quite that simple, but that will do as a simplified model to understand the issue). Each of the ObservableCollection<CartOrderAdd>
might contain different values.
Now whenever you click an item in your list, you are creating a new instance of type QuantityPopUp
var popup = new QuantityPopUp(_sender);
and hence a new instance of ObservableCollection<CartOrderAdd>
is created, which is empty by default. You are immediately adding a meal to it and on clicking OK you are proceeding to your checkout cart. Even if there are other meals that should've been added to your cart, they are somewhere in memory in some lists, but (of course) not in your newly created list.
I'd suggest MVVM with dependency injection and a framework like Prism. You could create a Cart
that gets injected in your viewmodels (please not that the added meals should either be persisted in memory or there should only be a single instance of Cart
). The signature could look like the follwoing
class Cart
{
public void AddOrder(string mealCode, int quantity);
public IReadOnlyCollection<Meal> GetAddedMeals();
}
Please note that only the mealCode
and the quantity
are passed, since it should not be up to the UI to determine the price (this would be redundant, error prone and potentially open the doors for abuses) and the name of the menu (not as crucial as the price, but still).
Now if you don't want/can't use MVVM with DI, you could make use of the Cart
object. E.g. by passing it around between the views or by using a singleton implementation (I'd recommend neither, but you can).
The code behind of your views could look like the following.
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();
}
// ...
}
Upvotes: 3