分组/嵌套列表视图

时间:2019-12-05 03:12:54

标签: c# ios listview xamarin binding

我正在开发库存管理器Xamarin iOS应用程序。我正在尝试创建一个页面,用户可以在其中添加库存,包括将一系列序列项添加到商店库存中。我需要的设计是一个包含多个条目的嵌套列表视图,如果第一个列表视图中的productId属于电话项目,则它将具有一个内部列表视图,其中包含用于serialNumber值(Stock.Quantity的大小)的条目。产品是配件,没有序列号。 我试过分组和嵌套ListViews,但无济于事。

股票类别:

public class Stock
{

    [Key]
    public int ProductId { get; set; }
    [Required]
    public int StoreId { get; set; }
    [Required]
    public int Quantity { get; set; }

    [JsonIgnore]
    public virtual Product Product { get; set; }
    [JsonIgnore]
    public virtual Store Store { get; set; }
    public virtual ICollection<SerialNumber> SerialNumbers { get; set; }
}

SerialNumber类:

 public class SerialNumber
{
    [ForeignKey("ProductId")]
    public int ProductId { get; set; }
    [ForeignKey("StoreId")]
    public int StoreId { get; set; }
    [Key]
    public string SerialNumberValue { get; set; }
    [JsonIgnore]
    public virtual Stock Stock { get; set; }

}

ViewModel类:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
using InventoryManager.Models;
using Xamarin.Forms;

namespace InventoryManager.ViewModels
{
public class AddStocksViewModel : BaseViewModel
{
    public AddStocksViewModel() {

        stocks = new ObservableCollection<Stock>();
        stocks.Add(new Stock() { StoreId = App.currentStore.StoreId, SerialNumbers = new ObservableCollection<SerialNumber>() });
        serialNumbers = new ObservableCollection<SerialNumber>();
        serialNumbers.Add(new SerialNumber());

    }
    public IList<Stock> stocks { get; set;  }
    public IList<SerialNumber> serialNumbers { get; set; }
    public IList<Stock> Stocks
    {
        get { return stocks; }
        set { stocks = value; }
    }


    public IList<SerialNumber> SerialNumbers {
        get { return serialNumbers; }
        set { serialNumbers = value; }

    }

    public int ProductId { get; set; }

    public ICommand ProductIdChanged {
        get
        {
            return GetProduct;
        }  
    }

    public bool IsProductAPhone { get; set; } 
    //public Stock  Stock {get;set;}
    public Product Product { get; set; } 
    public ICommand GetProduct
    {
        get
        {
            return new Command(async () =>
            {
                try
                {
                    Product = await DataStore.GetProductAsync(ProductId);
                }
                catch
                {


                }
                finally
                {
                    if (Product != null)
                        IsProductAPhone = Product.ProductType == ProductType.Phone;
                }
            });
        }
    }
}
}

在后面添加股票页面代码

 using System;
    using System.Collections.Generic;
    using InventoryManager.ViewModels;
    using Xamarin.Forms;
    using InventoryManager.Models;
namespace InventoryManager.Views
{
public partial class AddStocksPage : ContentPage
{
    AddStocksViewModel viewModel;

    public AddStocksPage()
    {
        InitializeComponent();
        BindingContext = viewModel = new AddStocksViewModel();


    }
    public void OnProductIdChanged(object sender, TextChangedEventArgs args)
    {
        viewModel.GetProduct.Execute(null);
        //viewModel.Product.Id = (args.NewTextValue);
    }
    public void OnQuantityChanged(object sender, TextChangedEventArgs args)
    {
        try
        {
            int quantity = Int32.Parse((sender as Entry).Text);
            if (viewModel.IsProductAPhone)
            {
                for (int i = 0; i < quantity; i++)
                    viewModel.SerialNumbers.Add(new SerialNumber());

            }
        }
        catch {

        }
        //viewModel.Product.Id = (args.NewTextValue);
    }
    public void AddItemClicked (object sender, EventArgs args){
        viewModel.Stocks.Add(new Stock { StoreId = App.currentStore.StoreId });
    }
}

}

** AddStocksPage XAML代码:我尝试了两种方法,一种被注释掉了**

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="InventoryManager.Views.AddStocksPage"
            xmlns:viewmodels="clr-namespace:InventoryManager.ViewModels">
    <ContentPage.ToolbarItems>
    <ToolbarItem Text="Add" Clicked="AddItemClicked" />
</ContentPage.ToolbarItems>
<ContentPage.BindingContext>
    <viewmodels:AddStocksViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>

  <StackLayout>

      <ListView x:Name="stockListView" IsGroupingEnabled="True" ItemsSource="{Binding Stocks}" >
          <ListView.GroupHeaderTemplate>
              <DataTemplate>
        <ViewCell>
                    <StackLayout Spacing="3" Orientation="Horizontal" >
                     <Entry Text="{Binding ProductId}"  Placeholder="Product Id" TextChanged="OnProductIdChanged"  x:Name="productIdEntry" />
                     <Entry Text="{Binding StoreId}"  Placeholder="Store Id" IsEnabled="False"/>
                     <Entry Text="{Binding  Source={x:Reference quantityStepper}, Path=Value, StringFormat='{0}'}" Placeholder="Quantity" TextChanged="OnQuantityChanged" />
                     <Stepper x:Name="quantityStepper"   Maximum="360" Increment="1"  HorizontalOptions="Center" Value="{Binding Quantity}" />
                     </StackLayout>
        </ViewCell>
               </DataTemplate>

              </ListView.GroupHeaderTemplate>
           <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout>
                              <Entry Text="{Binding SerialNumber.SerialNumberValue}" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>

      </ListView>

      </StackLayout>
        <!--<StackLayout>

    <ListView x:Name="stockListView" ItemsSource="{Binding Stocks}" IsGroupingEnabled="True"  >
            <ListView.ItemTemplate>
              <DataTemplate>
                <ViewCell>
                 <ViewCell.View>
                     <StackLayout Orientation= "Vertical" Spacing="3">
                    <StackLayout Spacing="3" Orientation="Horizontal" >
                     <Entry Text="{Binding ProductId}"  Placeholder="Product Id" TextChanged="OnProductIdChanged"  x:Name="productIdEntry" />
                     <Entry Text="{Binding StoreId}"  Placeholder="Store Id" IsEnabled="False"/>
                     <Entry Text="{Binding  Source={x:Reference quantityStepper}, Path=Value, StringFormat='{0}'}" Placeholder="Quantity" TextChanged="OnQuantityChanged" />
                     <Stepper x:Name="quantityStepper"   Maximum="360" Increment="1"  HorizontalOptions="Center" Value="{Binding Quantity}" />
                     </StackLayout>
                     <ListView x:Name="serialListView" ItemsSource="{Binding SerialNumbers}"   IsVisible="true" >
                         IsVisible="{ Binding IsProductAPhone}"
                     <ListView.ItemTemplate>
                         <DataTemplate>
                              <TextCell Text="{Binding SerialNumber.SerialNumberValue}" />
                         </DataTemplate>
                     </ListView.ItemTemplate>
                  </ListView>

                    </StackLayout> 
            </ViewCell.View>
          </ViewCell>


              </DataTemplate>
          </ListView.ItemTemplate>
      </ListView>
    </StackLayout>-->



</ContentPage.Content>

请让我知道任何提示/建议。任何有关如何实现此目标的示例代码将不胜感激

1 个答案:

答案 0 :(得分:1)

像Jason提到的那样,阅读了一些文档,我将在快速的Google搜索中为您提供一些信息。

我不会建议Nestled Listviews这只是一种不好的做法。我的诚实意见是停止并重新考虑这一点。

我宁愿说再看看Tableview还是Jason提到Grouped Listviews。有了Tableviews,您可以在页面加载时添加条件逻辑,然后添加到Tableview中。通过这种方式,您可以更好地控制发生了什么,没有什么,特别是如您所提到的,您想将库存/配件逻辑分开。

有关嵌套列表视图的主题:

https://forums.xamarin.com/discussion/100280/nested-listview-in-xamarin-forms-listview-inside-another-listview

列表视图分组: https://xamarinhelp.com/xamarin-forms-listview-grouping/

分组样本: https://docs.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/userinterface-listview-grouping/


在下面更新

行上有任何按钮吗?至少我认为,它们将是您最可靠的方式。因此,您要做的就是将按钮的BindingContex设置为“键”或具有的标识符,然后获取项目的上下文

引发事件args


 int check;

            var btn = (YourButton)sender;

            var item = btn.BindingContext; //You can find other Properties of the said Item aswell

            check = Convert.ToInt32(item);

在这里,如何在项目选择上执行id操作,而不是希望它对按钮有帮助


 var obj = (YourCollection)e.SelectedItem;
            var ide = Convert.ToInt32(obj.PId); //Get the Item's Id or w.e els youd like to grab from the collection


//Below is a little Example of how i'm getting the current indexed items ID To use for later
            foreach (var item in z)
            {
                if (ide == item.PId)
                {
                    currentID = item.PId;


                }
            }