在TabbedPage中填充选择器信息Xamarin表单

问题描述

我一直在尝试在选项卡式页面之间传输/填充数据。 我要执行的操作的总体思路是在“插入/编辑”页面中插入产品信息,然后可以在“概述”页面中查看该产品信息。保存的产品将填充到列表视图中。

我对MVVM和Xamarin非常陌生。 我遇到的问题是,当用户单击“概述”页面中的列表视图中的项目时,然后应在“插入/编辑”页面中填充存储的信息,以便用户可以编辑产品信息。 我可以显示除选择器以外的大多数产品信息。它只是显示为空。

enter image description here

我的Tabbedviewmodel错误吗?有人可以指出我正确的方向吗? 下面是我的选项卡式XAML代码

<TabbedPage 
... 
...>
    <Views:InsertEdit Title="Insert/Edit" Icon="edit.png" BindingContext="{Binding productviewmodel}"></Views:InsertEdit>
    <Views:Overview Title="Overview" Icon="list.png"></Views:Overview>
</TabbedPage>

我使用Tabbedviewmodel在“插入/编辑”页面和“概述”页面之间绑定产品信息

namespace Prototype
{
    public class Tabbedviewmodel
    {
        public Product productviewmodel { set; get; }

        public Tabbedviewmodel(Product product)
        {
            productviewmodel = product;
        }
    }
}

产品信息根据产品型号

public class Product
{
        [PrimaryKey,AutoIncrement]
        public int id { get; set; }
        public string productCode { get; set; }
        public string description { get; set; }
        public string merchant { get; set; }
        public string remarks { get; set; }
        public string conditionCode { get; set; }
        public string conditionName { get; set; }
        
}

产品条件符合ProductCondition模型

public class ProductCondition
{
        
        public string conditionCode { get; set; }
        public string conditionName { get; set; }
        
}

在选择器列表中,仅显示conditionName。 但是,当将产品信息保存到“产品”表中时,conditionName和conditionCode一起存储。

下面是我的InsertEdit内容页代码

public partial class InsertEdit : ContentPage
{
    Product product;

    public InsertEdit()
    {
        InitializeComponent();
        InitializeData();
    }
    
    private async void InitializeData()
    {
        List<ProductCondition> conditionList = await App.DbHelper.GetConditionListAsync();
        picker.ItemsSource = conditionList;
    }

    // Upon clicking enter key in the entry text field,search for product info based on the product code user has keyed in
    async void EditorProductCode_Completed(object sender,EventArgs e)
    {
        var text = ((Entry)sender).Text; //cast sender to access the properties of the Entry

        if (string.IsNullOrEmpty(text))
        {
            await displayAlert("Warning","Invalid","OK");
        }
        else
        {

            product = await App.DbHelper.GetProduct(text);
            populateData();
        }
    }

    async void populateData() {
        if (product == null)
        {
            product = new Product();
            product = null;
            await displayAlert("Warning","Invalid product code.","OK");
        }

        picker.SelectedItem = ((List<ProductCondition>)picker.ItemsSource).FirstOrDefault(c => c.conditionCode == product.conditionCode);

        BindingContext = product;
    }

   
   // Upon clicking the save button
    async void OnSaveButtonClicked(object sender,EventArgs e)
    {
        product.conditionCode = ((ProductCondition)picker.SelectedItem).conditionCode;
        product.conditionName = ((ProductCondition)picker.SelectedItem).conditionName;
        await App.DbHelper.SaveProductAsync(product);

        DependencyService.Get<IMessage>().Longalert("Product has been saved!");

    }

}

下面是选择器的xaml代码

<Grid>
    <Grid.ColumnDeFinitions>
        <ColumnDeFinition Width="2.1*" />
        <ColumnDeFinition Width="*" />
        <ColumnDeFinition Width="5*" />
    </Grid.ColumnDeFinitions>
    <Label Text="Product Condition" 
       HorizontalOptions="Start"
       VerticalOptions="Center"/>
    <Label Grid.Column="1"
       HorizontalOptions="Start"
       VerticalOptions="Center"
       Text=":"/>
    <Picker Grid.Column="2"
        Title="Select Condition" 
        x:Name="picker" 
        FontSize="13"
        ItemdisplayBinding="{Binding conditionName}"
        />
</Grid>

下面是我的InsertEdit内容页代码

public partial class Overview : ContentPage
{
    public Overview()
    {
        InitializeComponent();
    }

    protected override async void OnAppearing()
    {
        base.OnAppearing();

        Quantity.Text = "Quantity : " + (await App.DbHelper.GetProductTableCount()).ToString();

        lvItems.BeginRefresh();

        List<Product> productList = await App.DbHelper.GetProductListAsync();

        lvItems.ItemsSource = productList;
        lvItems.EndRefresh();

    }

    async void OnListViewItemSelected(object sender,selecteditemchangedEventArgs e)
    {
        if (e.SelectedItem != null)
        {
            Product product = e.SelectedItem as Product;

            var tab = this.Parent as TabbedPage;
            tab.BindingContext = new Tabbedviewmodel(product);
            tab.CurrentPage = tab.Children[0];

            /*await Navigation.PushAsync(new TabbedPage
            {
                BindingContext = new Tabbedviewmodel(product)
            });*/
        }
    }
}

如果有人能指出我正确的方向,我将不胜感激。我已经尝试了好几天,上面的代码是我能拿出的最好的代码。我只是失去了对如何填充选择器的信息。

解决方法

在“产品类”中添加ProductCondition类对象,然后填充。

public class Product
{
        [PrimaryKey,AutoIncrement]
        public int id { get; set; }
        public string productCode { get; set; }
        public string description { get; set; }
        public string merchant { get; set; }
        public string remarks { get; set; }
        public ProductCondition productCondition { get; set; }            
}

在选择器中添加SelectedItem

<Picker Grid.Column="2"
        Title="Select Condition" 
        x:Name="picker" 
        FontSize="13"
        ItemDisplayBinding="{Binding conditionName}"
        SelectedItem="{Binding MyItemSelected,Mode="TwoWay"}"
        />

ViewModel

private ProductCondition myItemSelected = new ProductCondition();

public ProductCondition MyItemSelected
{
  get => myItemSelected;
  set
  {
     myItemSelected = value;
     OnPropertyChanged("MyItemSelected");
  }
}

然后在导航之前

MyItemSelected = selectedProduct.productCondition;