【问题标题】:Populate picker info in TabbedPage (Xamarin forms)在 TabbedPage 中填充选取器信息(Xamarin 表单)
【发布时间】:2020-10-21 10:17:35
【问题描述】:

我一直在尝试在标签页之间传输/填充数据。 我想要做的一般想法是在“插入/编辑”页面中插入产品信息,然后可以在“概述”页面中查看。保存的产品填充在列表视图中。

我对 MVVM 和 Xamarin 非常陌生。 我遇到问题的场景是当用户从“概览”页面的列表视图中单击一个项目时,它应该在“插入/编辑”页面中填充存储的信息,以便用户可以编辑产品信息。 我能够显示除选择器之外的大部分产品信息。它只是显示为空。

我的 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; }
        
}

在选择器列表中,仅显示条件名称。 但是将产品信息保存到产品表中时,条件名称和条件代码是存储在一起的。

下面是我的 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)
            });*/
        }
    }
}

如果有人能指出正确的方向,我真的很感激。我已经尝试了好几天,上面的代码是我能想到的最好的。我只是迷失了如何填充选择器信息。

【问题讨论】:

    标签: xamarin xamarin.forms mvvm picker


    【解决方案1】:

    在 Product Class 中添加 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"}"
            />
    

    视图模型

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

    然后在您导航之前

    MyItemSelected = selectedProduct.productCondition;
    

    【讨论】:

    • 您好,感谢您的反馈。但是我可以知道我应该把这行代码MyItemSelected = selectedProduct.productCondition; 放在哪里吗?此外,您的答案中的 ViewModel 与 TabbedViewModel 相同吗?还是我需要创建一个新的类调用ViewModel?
    • @K.Yen 将代码行放在导航前映射下一页的位置。并且视图模型代码也在放置第2页绑定的页面中
    猜你喜欢
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多