微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

xamarin 表单 - 选择器在页面加载时不显示任何值

如何解决xamarin 表单 - 选择器在页面加载时不显示任何值

将 MVVM 与 xamarin 形式一起使用。 ProductPage 包含产品的 ListView。每个产品都有一个选择器。 用户选择他们想要购买的商品数量用户点击购物车图片。 ShoppingCartPage 加载显示用户选择的项目,但选择器是空白的。我希望选择器显示从 productaPage 中选择的数量 我已经逐步完成了后面的代码

Model.ListQuantites = List_Quantites;
Model.SelectedQuantity = Model.ListQuantites.SingleOrDefault(p => p.Key == tempQuantity.Key && p.Value == tempQuantity.Value)

在 ShoppingCartPage 的 OnAppearing() 上存储了正确的数量值,但我不明白为什么选择器没有显示正确的值。

已尝试以下所有建议:

How to Display Picker when page load without tapping on title Xamarin.Forms

https://forums.xamarin.com/discussion/153788/set-a-picker-selecteditem-on-page-startup

xamarin.forms Update Listview with picker

Item to Display for Picker don't show up on load

但仍然无法正常工作有没有人知道我做错了什么?

感谢您的建议

 public class ProductModel : INotifyPropertyChanged
    {
       
        //Event
        public event PropertyChangedEventHandler PropertyChanged;

        //Fields
        //[PrimaryKey,AutoIncrement]
        private int _ProductId;
        private string _ProductName;
        private string _Quantity;
        private string _Description;
        private string _Image;
        private decimal _Price;
        private decimal _SubTotalForItem;
        private string _Genre;
        public ObservableCollection<Quantity> _ListQuantites;

        //Constructor
        public ProductModel()
        {
            //Subscription
            this.PropertyChanged += OnPropertyChanged;
        }

        [PrimaryKey,AutoIncrement]
        public int ProductId
        {
            get { return _ProductId; }
            set
            {
                if (_ProductId == value) return;
                _ProductId = value;
                OnPropertyChanged();
            }
        }
     

        //Properties
        public string Quantity
        {
            get
            {
                return _Quantity;
            }
            set
            {
                _Quantity = value;
                OnPropertyChanged();
            }
        }

        public ObservableCollection<Quantity> ListQuantites
        {
            get
            {
                return _ListQuantites;
            }
            set
            {
                _ListQuantites = value;
                OnPropertyChanged();
            }
        }

        private Quantity _selectedQuantity;
        public Quantity SelectedQuantity
        {
            get
            {
                return _selectedQuantity;
            }
            set
            {
                if (value == null)
                {
                    _selectedQuantity = _selectedQuantity;
                }
                else
                {
                    _selectedQuantity = value;
                    OnPropertyChanged();
                }
            }
        }

        [MaxLength(50)]
        public string Description
        {
            get
            {
                return _Description;
            }
            set
            {
                _Description = value;
                OnPropertyChanged();
            }
        }

        public string Image
        {
            get
            {
                return _Image;
            }
            set
            {
                _Image = value;
                OnPropertyChanged();
            }
        }

        public decimal Price
        {
            get
            {
                return _Price;
            }
            set
            {
                _Price = value;
                OnPropertyChanged();
            }
        }

        public decimal SubTotalForItem
        {
            get
            {
                return _SubTotalForItem;
            }
            set
            {
                _SubTotalForItem = value;
                OnPropertyChanged();
            }
        }

        public string Genre
        {
            get
            {
                return _Genre;
            }
            set
            {
                _Genre = value;
                OnPropertyChanged();
            }
        }


        public string ProductName
        {
            get { return _ProductName; }
            set
            {
                _ProductName = value;
                OnPropertyChanged();
            }
        }

        
        //OnPropertyChanged
        private void OnPropertyChanged(object sender,PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(SelectedQuantity))
            {
                //test quantity amount
            }
        }

        // [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
        }

    }


----------------
 public class Quantity
    {
        public int Key { get; set; }
        public string Value { get; set; }
    }
----------------
 public class PickerService
    {
        public static ObservableCollection<Quantity> GetQuantitiesForProductPage()
        {
            var quantities = new ObservableCollection<Quantity>()
            {
                new Quantity() {Key=1,Value="0"},new Quantity() {Key=2,Value="1"},new Quantity() {Key=3,Value="2"},new Quantity() {Key=4,Value="3"},new Quantity() {Key=5,Value="4"},new Quantity() {Key=6,Value="5"},new Quantity() {Key=7,Value="6"},new Quantity() {Key=8,Value="7"},new Quantity() {Key=9,Value="8"},new Quantity() {Key=10,Value="9"},new Quantity() {Key=11,Value="10"}
            };
            return quantities;
        }

        public static ObservableCollection<Quantity> GetQuantitiesForShoppingcart()
        {
            var quantities = new ObservableCollection<Quantity>()
            {
                new Quantity() {Key=1,Value="10"},};
            return quantities;
        }
    }
--------------
 public class ShoppingCartviewmodel //: INotifyPropertyChanged
    {
        private ObservableCollection<ProductModel> _shoppingCartList;
        public ObservableCollection<ProductModel> ShoppingCartList
        {
            get
            {
                return _shoppingCartList;
            }
            set
            {
                if (_shoppingCartList == value) return;
                _shoppingCartList = value;
            }
        }

        public ShoppingCartviewmodel()
        {
            ShoppingCartList = new ObservableCollection<ProductModel>();
        }

    }
----------------
 [XamlCompilation(XamlCompilationoptions.Compile)]
    public partial class ShoppingCartPage : ContentPage
    {
        ShoppingCartviewmodel ShoppingCartviewmodel = new ShoppingCartviewmodel();
        public decimal TotalForAllItems;
        public ObservableCollection<Quantity> List_Quantites { get; set; }

        public ShoppingCartPage()
        {
            InitializeComponent();
            BindingContext = ShoppingCartviewmodel;
        }

        public int CalculateQuantityOfItemsInShoppingCart()
        {
            int quantityOfProducts = 0;

            if (ShoppingCartviewmodel.ShoppingCartList != null)
            {
                foreach (var product in ShoppingCartviewmodel.ShoppingCartList)
                {
                    if (product.SelectedQuantity != null)
                    {
                        quantityOfProducts += Convert.ToInt32(product.SelectedQuantity.Value);
                    }
                }
            }

            return quantityOfProducts;
        }

        protected override void Ondisappearing()
        {
            App.globalShoppingCartOC = ShoppingCartviewmodel.ShoppingCartList;
        }

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

            TotalForAllItems = 0.00M;

            List_Quantites = PickerService.GetQuantitiesForShoppingcart();

            ShoppingCartviewmodel.ShoppingCartList.Clear();

            if (App.globalShoppingCartOC != null)
            {
                foreach (ProductModel Model in App.globalShoppingCartOC)
                {
                    if (Model.SelectedQuantity != null)
                    {
                        var _quantity = Convert.ToDecimal(Model.SelectedQuantity.Value);
                        if (_quantity > 0)
                        {
                            Model.SubTotalForItem = _quantity * Model.Price;
                            //this line resets Model.SelectedQuantity to 0,so need to re-populate with tempQuantity value
                            Quantity tempQuantity = Model.SelectedQuantity;
                            Model.ListQuantites = List_Quantites;
                            Model.SelectedQuantity = Model.ListQuantites.SingleOrDefault(p => p.Key == tempQuantity.Key && p.Value == tempQuantity.Value);
                            ShoppingCartviewmodel.ShoppingCartList.Add(Model);
                            TotalForAllItems += Model.SubTotalForItem;
                        }
                    }
                }

                SubTotalForAllItems.Text = TotalForAllItems.ToString();
            }

            NoItemsInShoppingCart.Text = CalculateQuantityOfItemsInShoppingCart().ToString();
        }

        protected async void SI_Invoked(object sender,EventArgs e)
        {
            var si = sender as SwipeItem;
            var productToRemove = si.CommandParameter as ProductModel;

            var action = await displayAlert("Are you sure you want to remove ",productToRemove.ProductName + ".","Yes","No");

            if (action)
            {
                ShoppingCartviewmodel.ShoppingCartList.Remove(productToRemove);

                Quantity tempQuantity = productToRemove.SelectedQuantity;
                decimal tempQuantityValue = Convert.ToDecimal(tempQuantity.Value);
                decimal subtotalToRemove = productToRemove.Price * tempQuantityValue;
                TotalForAllItems -= subtotalToRemove;
                SubTotalForAllItems.Text = TotalForAllItems.ToString();

                NoItemsInShoppingCart.Text = CalculateQuantityOfItemsInShoppingCart().ToString();
            }
        }

        public void SCQuantityAndSubtotalUpdated(object sender,EventArgs e)
        {
            TotalForAllItems = 0.00M;

            if (ShoppingCartviewmodel.ShoppingCartList != null)
            {
                foreach (ProductModel Model in ShoppingCartviewmodel.ShoppingCartList)
                {
                    var _quantity = Convert.ToDecimal(Model.SelectedQuantity.Value);
                    if (_quantity > 0)
                    {
                        Model.SubTotalForItem = _quantity * Model.Price;
                        TotalForAllItems += Model.SubTotalForItem;
                    }
                }

                SubTotalForAllItems.Text = TotalForAllItems.ToString();
            }


            NoItemsInShoppingCart.Text = CalculateQuantityOfItemsInShoppingCart().ToString();
        }

        private void PlaceOrder_BtnClicked(object sender,EventArgs e)
        {

        }
    }
-------------------------
   <ContentPage.toolbaritems>
        <ToolbarItem Name="shoppingCartImg" Icon="shopping_cart.png" Priority="0" Order="Primary"/>
        <ToolbarItem x:Name="NoItemsInShoppingCart" Priority="0" Order="Primary"/>
    </ContentPage.toolbaritems>

    <ContentPage.Content>
        <StackLayout>
            <ListView ItemsSource="{Binding ShoppingCartList}"  IsVisible="True" VerticalOptions="FillAndExpand" HasUnevenRows="True">
                <ListView.Header>
                    <Button Text="Place Order" Clicked="PlaceOrder_BtnClicked"/>
                </ListView.Header>
                <ListView.Footer>
                    <Label x:Name="SubTotalForAllItems" HorizontalTextAlignment="End" VerticalTextAlignment="Start" Margin="20,20" FontAttributes="Bold"/>
                </ListView.Footer>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <swipeview>
                                    <swipeview.LeftItems>
                                        <SwipeItems Mode="Reveal">
                                            <SwipeItem Text="Details" IconImageSource="xamarin_logo.png" CommandParameter="{Binding .}" BackgroundColor="LightBlue" Invoked="SI_Invoked">
                                            </SwipeItem>
                                        </SwipeItems>
                                    </swipeview.LeftItems>
                                    
                                    <!--Content of Swipe View -->
                                    <StackLayout BackgroundColor="Green" HorizontalOptions="StartAndExpand">
                                        
                                    <Grid>
                                        <Grid.RowDeFinitions>
                                            <RowDeFinition Height="Auto"/>
                                        </Grid.RowDeFinitions>
                                        <Grid.ColumnDeFinitions>
                                            <ColumnDeFinition Width="Auto"/>
                                        </Grid.ColumnDeFinitions>

                                        <Label Grid.Column="0" Grid.Row="0" Text="{Binding ProductId}" VerticalOptions="End" IsVisible="False"/>
                                        <controls:CircleImage  Grid.Column="1"  Grid.Row="0" HeightRequest="60" HorizontalOptions="CenterandExpand" VerticalOptions="Center" Aspect="AspectFill" WidthRequest="66" Grid.RowSpan="2" Source="{Binding Image}"/>
                                        <Label Grid.Column="2" Grid.Row="0" Text="{Binding ProductName}" VerticalOptions="Start"/>
                                        <Label Grid.Column="2" Grid.Row="1"  Text="{Binding Description}" VerticalOptions="End"/>
                                            <Label Grid.Column="3" Grid.Row="0" VerticalOptions="Start" Text="{Binding SubTotalForItem,StringFormat='£{0:0.00}'}"/>
                                          
                                            <Picker x:Name="scPicker" ItemsSource="{Binding ListQuantites,Mode=TwoWay}" SelectedItem="{Binding SelectedQuantity,Mode=TwoWay}" ItemdisplayBinding="{Binding Value}" SelectedindexChanged="SCQuantityAndSubtotalUpdated"/>
                                        </Grid>
                                    </StackLayout>
                                </swipeview>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>


        </StackLayout>
    </ContentPage.Content>

-------------------------
    [XamlCompilation(XamlCompilationoptions.Compile)]
    public partial class ProductPage : ContentPage
    {
        public ProductPageviewmodel productPage_ViewModal;
        MainPage RootPage { get => Application.Current.MainPage as MainPage; }

        public ProductPage()
        {
            InitializeComponent();
            productPage_ViewModal = new ProductPageviewmodel();
            BindingContext = productPage_ViewModal;
        }

        protected override void Ondisappearing()
        {
            App.globalShoppingCartOC = productPage_ViewModal.WineList;
        }

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

            if (App.globalShoppingCartOC != null)
            {
                //First need to check shoppingCart list for product,if it has been removed in SC,//then set quantity to 0
                foreach (var product in productPage_ViewModal.WineList)
                {
                    var doesProductExistInShoppingCart = App.globalShoppingCartOC.Where(x => x.ProductId == product.ProductId).FirstOrDefault();

                    if(doesProductExistInShoppingCart == null)
                    {
                        if (productPage_ViewModal.WineList.Where(x => x.ProductId == product.ProductId).FirstOrDefault().SelectedQuantity != null)
                        {
                            Quantity tempQuantity = new Quantity() { Key = 1,Value = "0" };
                            product.SelectedQuantity = productPage_ViewModal.List_Quantites.SingleOrDefault(p => p.Key == tempQuantity.Key && p.Value == tempQuantity.Value);
                            product.ListQuantites = PickerService.GetQuantitiesForProductPage();
                            // productPage_ViewModal.WineList.Where(x => x.ProductId == product.ProductId).FirstOrDefault().SelectedQuantity.Value = "0";
                        }
                    }
                }

                //Can then update correct quantity for other products still in SC list
                foreach (var product in App.globalShoppingCartOC)
                {
                    if (productPage_ViewModal.WineList.Where(x => x.ProductId == product.ProductId).FirstOrDefault().SelectedQuantity != null)
                    {
                        Quantity tempQuantity = product.SelectedQuantity;
                        product.SelectedQuantity = productPage_ViewModal.List_Quantites.SingleOrDefault(p => p.Key == tempQuantity.Key && p.Value == tempQuantity.Value);
                        product.ListQuantites = PickerService.GetQuantitiesForProductPage();
                        //productPage_ViewModal.WineList.Where(x => x.ProductId == product.ProductId).FirstOrDefault().SelectedQuantity.Value = product.SelectedQuantity.Value;
                    }
                }
            }

            NoItemsInShoppingCart.Text = CalculateQuantityOfItemsInShoppingCart().ToString();
        }

        private async void ShoppingCartClicked(object sender,EventArgs e)
        {
            MenuPage tempMenu = new MenuPage();
             int IdOfMenuClicked = tempMenu.GetIdForNavigationMenu("Shopping Cart");
            await RootPage.NavigateFromMenu(IdOfMenuClicked);
        }

        public void QuantityChanged(object sender,EventArgs e)
        {
            NoItemsInShoppingCart.Text = CalculateQuantityOfItemsInShoppingCart().ToString();
        }

        public int CalculateQuantityOfItemsInShoppingCart()
        {
            int quantityOfProducts = 0;

            if (productPage_ViewModal.WineList != null)
            {
                foreach (var product in productPage_ViewModal.WineList)
                {
                    if (product.SelectedQuantity != null)
                    {
                        quantityOfProducts += Convert.ToInt32(product.SelectedQuantity.Value);
                    }
                }
            }

            return quantityOfProducts;
        }
    }
-------------------------
            Title="ProductPage">
    <ContentPage.toolbaritems>
        <ToolbarItem Name="shoppingCartImg" Icon="shopping_cart.png" Priority="0" Order="Primary" Activated="ShoppingCartClicked"/>
        <ToolbarItem x:Name="NoItemsInShoppingCart" Priority="0" Order="Primary" Activated="ShoppingCartClicked"/>
    </ContentPage.toolbaritems>

    <ContentPage.Content>
        <StackLayout>

            <ListView IsVisible="True" VerticalOptions="FillAndExpand" HasUnevenRows="True" ItemsSource="{Binding WineList}"> <!--HeightRequest="1500"-->
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout BackgroundColor="Green" HorizontalOptions="StartAndExpand">
                                <Grid>
                                    <Grid.RowDeFinitions>
                                        <RowDeFinition Height="Auto"/>
                                    </Grid.RowDeFinitions>
                                    <Grid.ColumnDeFinitions>
                                        <ColumnDeFinition Width="Auto"/>
                                    </Grid.ColumnDeFinitions>
                                    <Label Grid.Column="0" Grid.Row="0" Text="{Binding ProductId}" VerticalOptions="End" IsVisible="False"/>
                                    <controls:CircleImage  Grid.Column="1"  Grid.Row="0" HeightRequest="60" HorizontalOptions="CenterandExpand" VerticalOptions="Center" Aspect="AspectFill" WidthRequest="66" Grid.RowSpan="2" Source="{Binding Image}"/>
                                    <Label Grid.Column="2" Grid.Row="0" Text="{Binding ProductName}" VerticalOptions="Start"/>
                                    <Label Grid.Column="2" Grid.Row="1"  Text="{Binding Description}" VerticalOptions="End"/>
                                    <Label Grid.Column="3" Grid.Row="0" VerticalOptions="Start" Text="{Binding Price,StringFormat='£{0:0.00}'}"/>
                                    <Picker x:Name="productPicker" ItemsSource="{Binding ListQuantites}" ItemdisplayBinding="{Binding Value}" SelectedindexChanged="QuantityChanged" SelectedItem ="{Binding SelectedQuantity}"/>
                                </Grid>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            
        </StackLayout>

    </ContentPage.Content>
    </ContentPage>
----------------------------------------------
 public class ProductPageviewmodel : BindableObject,INotifyPropertyChanged
    {
        public ObservableCollection<ProductModel> WineList { get; set; }

        public ObservableCollection<Quantity> List_Quantites { get; set; }

        public ProductPageviewmodel()
        {
            List_Quantites = PickerService.GetQuantitiesForProductPage();//.OrderBy(c => c.Value).ToList();

            WineList = new ObservableCollection<ProductModel>();
            WineList.Add(new ProductModel { ProductId = 1,ProductName = "Wine 1",ListQuantites = List_Quantites,Image = "wine.jpg",Quantity = "0",Description = "700ml",Price = 10.00M,SubTotalForItem = 0.00M,Genre = "Wine" });
            WineList.Add(new ProductModel { ProductId = 2,ProductName = "Wine 2",Genre = "Wine" });
            WineList.Add(new ProductModel { ProductId = 3,ProductName = "Wine 3",Price = 5.50M,Genre = "Wine" });
            WineList.Add(new ProductModel { ProductId = 4,ProductName = "Wine 4",Genre = "Wine" });
        }

更新

在 ProductPage 上,如果用户更改了产品的数量,它会在 productPage_ViewModal.WineList 中自动更新,

用户点击 ShoppingCart 图标 Ondisappearing() 在 ProductPage 上被调用时,将 productPage_ViewModal.WineList 添加global ObservableCollection<ProductModel> globalShoppingCartOC,(存储在 App.xaml.cs 页面中)

从 ShoppingCartPage.xaml.cs 中的 OnAppearing() 开始,ShoppingCartviewmodel.ShoppingCartList 是通过遍历 globalShoppingCartOC 来填充的,

如果数量大于 0,添加到 ShoppingCartviewmodel.ShoppingCartList,并预先选择在选择器中选择的数量

Quantity tempQuantity = Model.SelectedQuantity;
Model.ListQuantites = List_Quantites;
Model.SelectedQuantity = Model.ListQuantites.SingleOrDefault(p => p.Key == tempQuantity.Key && p.Value == tempQuantity.Value);

问题是我可以通过逐步执行代码看到“Model.SelectedQuantity”将存储正确的值,但它不会使用选择器在 ShoppingCart 屏幕上更新

<Picker x:Name="scPicker" Title="--Select--" ItemsSource="{Binding ListQuantites,Mode=TwoWay}" ItemdisplayBinding="{Binding Value}" SelectedindexChanged="SCQuantityAndSubtotalUpdated"/>

解决方法

根据您的代码,我发现 PickerService.GetQuantitiesForProductPage() PickerService.GetQuantitiesForShoppingcart() 会得到不同的列表,

ProductPage Picker itemsource:

public static ObservableCollection<Quantity> GetQuantitiesForProductPage()
    {
        var quantities = new ObservableCollection<Quantity>()
        {
            new Quantity() {Key=1,Value="0"},new Quantity() {Key=2,Value="1"},new Quantity() {Key=3,Value="2"},new Quantity() {Key=4,Value="3"},new Quantity() {Key=5,Value="4"},new Quantity() {Key=6,Value="5"},new Quantity() {Key=7,Value="6"},new Quantity() {Key=8,Value="7"},new Quantity() {Key=9,Value="8"},new Quantity() {Key=10,Value="9"},new Quantity() {Key=11,Value="10"}
        };
        return quantities;
    }

ShoppingCartPage Picker 项目来源:

public static ObservableCollection<Quantity> GetQuantitiesForShoppingcart()
    {
        var quantities = new ObservableCollection<Quantity>()
        {
            new Quantity() {Key=1,Value="10"},};
        return quantities;
    }

所以从ProductPage选择的SelectedQuantity,在ShoppingCartPage Picker itemsource中找不到。 ShoppingCartPage 中的 Picker 不会显示数据。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。