c# - 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());
}
}
解决方案
您的问题很简单,但被您提供的大量代码所遮挡。下次您应该尝试将其归结为最小、完整和可验证的示例。
该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();
}
// ...
}
推荐阅读
- react-hooks - 如何在`useLazyLoadQuery`中跳过请求
- c++ - 尝试使用 TransmitFile 发送大文件会导致错误代码 87(错误参数)
- pyspark - 在 PySpark 数据框中创建的二进制列不能用作过滤器?
- verilog - verilog $基于时间的时钟周期
- javascript - 尝试在 ChartsJS 中为饼图插入另一个标签
- javascript - 如何更改 FlatList 中 TextInput 组件的道具?
- python - 如何自动激活python虚拟环境?
- sql-server - 如何使用多个表执行 OLAP 查询以执行 TOP N 销售?
- excel - 如何根据单元格值锁定 Excel 中的单元格行?
- docker - WSL2 无法连接到 Docker 守护程序