xamarin 表单 - 与选择器的双向绑定 - 为什么我不能从后面的代码更新选择器? [英] xamarin forms - two way binding with a picker - why cant I update a picker from code behind?

查看:45
本文介绍了xamarin 表单 - 与选择器的双向绑定 - 为什么我不能从后面的代码更新选择器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的产品页面只显示产品名称"和数量",数量显示/绑定到选择器.

My products page only shows 'Product Name' and 'Quantity', quantity isdisplayed/ binded to the picker.

出于测试目的以使其正常工作,只有 2 个产品从 VM 加载.葡萄酒 1 和葡萄酒 2.

For test purposes to get this working there is only 2 products loading from the VM. Wine 1 and wine 2.

当应用程序加载时,为什么选择器是空的,没有选择任何值.当每个项目的数量设置为 1 时,当从 VM 加载时

Quantity 设置为 1,选择器在最初加载时没有更新,我知道这是因为如果我点击空选择器并选择 1.没有任何反应,因为代码命中

Quantity is set to 1, the picker is just not updating when it initially loads, I know this because if I click on the empty picker and select 1. nothing happens because the code hits

if (quantity != value)

//其中被选择的数量1在后面的代码中已经是1,所以不会在数量上从setter调用propertyChanged,

// where quantity 1 being selected is already 1 in code behind, so wont call propertyChanged from setter in quantity,

还有...如果我选择选择器并选择另一个数字,例如说 4.数量设置器被命中,OnPropertyChanged 被命中,4 显示在选择器上.(如果选择了 3,我什至测试了更改产品名称)这奏效了.

also... if I select the picker and choose another number, say 4 for example. the setter in quantity is hit and OnPropertyChanged is hit, and 4 is displayed on the picker. (I even tested changing the productName if 3 was picked) and this worked.

我知道这一切都有效,因为我已经逐步完成了代码.然而,现在发生的另一个问题是,由于某种原因,代码在每次点击后都会再次点击 get/set 数量并将值设置为 0.

I know this all works as I have stepped through the code. However another issue that is now happening is that for some reason the code is hitting the quantity get/set AGAIN and setting the value to 0, after everytime it is clicked.

例如,如果点击 4,选择器将在屏幕上更新为 4,然后如果我通过步进代码来跟踪它,再次调用数量中的设置器,将值设置为 0,从而不选择任何内容在选择器中.将其留空,就像它最初加载时一样.

So for example if 4 is clicked, the picker will be updated to 4 on screen, then if I follow it through stepping in the code, the setter in quantity is called again, setting the value to 0, and thus selecting nothing in the picker. Leaving it blank, as it is when it initially loads.

任何帮助解决此问题的帮助将不胜感激,谢谢

any help to help resolve this would be appreciated thank Y

感谢 Y 提供的任何帮助

thank Y for any help received

public class ProductModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private int quantity;
        private string productName;

        public ProductModel()
        { }

        [PrimaryKey, AutoIncrement]
        public int ProductId { get; set; }

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

        public int Quantity
        {
            get
            {
                return quantity;
            }
            set
            {
                if (quantity != value)
                {
                    quantity = value;
                    OnPropertyChanged();

                    //test to check if binding works, successfully changed ProductName to "test" if 3 is picked from picker
                    if (quantity == 3)
                        ProductName = "test;";
                }

            }
        }
        protected void OnPropertyChanged([CallerMemberName] string name = null)
        {
            var changed = PropertyChanged;
            if (changed == null)
                return;

            changed.Invoke(this, new PropertyChangedEventArgs(name));
        }

    }
    public class ProductPageViewModel : BindableObject
        {
           public ObservableCollection<ProductModel> WineList { get; set; }
            public ProductPageViewModel ()
            {
                WineList = new ObservableCollection<ProductModel>();
                WineList.Add(new ProductModel { ProductId = 1, ProductName = "Wine 1", Quantity = 1});
                WineList.Add(new ProductModel { ProductId = 2, ProductName = "Wine 2", Quantity = 1});
            }
   
        
    
    
 <?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="ScrollApp2.Views.ProductPage">
    <ContentPage.Content>
        <StackLayout>
         
            <ListView  x:Name="producttablelist" IsVisible="True" VerticalOptions="FillAndExpand" HasUnevenRows="True" ItemsSource="{Binding WineList}" HeightRequest="1500">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout HeightRequest="120" BackgroundColor="Green" HorizontalOptions="StartAndExpand">
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="Auto"/>
                                    </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Label Grid.Row="0" Grid.Column="0" Text="{Binding ProductName}" TextColor="Black" VerticalOptions="Start"></Label>

                                    <Picker Grid.Column="1" Grid.Row="0" SelectedItem="{Binding Quantity,Mode=TwoWay}">
                                        <Picker.Items>
                                            <x:String>0</x:String>
                                            <x:String>1</x:String>
                                            <x:String>2</x:String>
                                            <x:String>3</x:String>
                                            <x:String>4</x:String>
                                            <x:String>5</x:String>
                                            <x:String>6</x:String>
                                        </Picker.Items>
                                    </Picker>
                                </Grid>
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

            
        </StackLayout>
       
    </ContentPage.Content>
</ContentPage>

    
   namespace ScrollApp2.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class ProductPage : ContentPage
    {
        public ProductPage()
        {
            InitializeComponent();
            BindingContext = new ProductPageViewModel();
        }
    }
}

推荐答案

你的 ProductModel 类不是从 INotifyPropertyChanged 接口继承的,你需要添加类的接口并实现它,同时确保在 Quantity setter 中引发 INotifyPropertyChanged.PropertyChanged 事件.

Your ProductModel class does not inherit from INotifyPropertyChanged interface, you’ll need to add the interface to your class and implement it, also making sure to raise the INotifyPropertyChanged.PropertyChanged event in Quantity setter.

此时您可能想要创建一个 ProductViewModel,因为我不确定您是否想将 INotifyPropertyChanged 添加到像 ProductModel.

You might want to create a ProductViewModel at this point, as I’m not sure you want to add INotifyPropertyChanged to a POCO class like ProductModel.

请不要用不同的问题编辑您的问题,请打开一个新问题.您之前的问题可能已经帮助其他人在更改不是从 IPropertyChanged 继承的类的属性时面临同​​样的 UI 未更新问题.我之前的回答现在与新问题无关,并且永远不会对其他人有益.

Please don't edit your question with a different one, open a new question. Your previous question might have helped someone else facing the same problem of UI not being updated when changing a property of a class that does not inherit from IPropertyChanged. My previous answer is now irrelevant to the new question, and will never benefit anyone else.

对于你的新问题,你的 Quantityint 类型,你的选择器项目是 string 类型,改变 Quantity 键入 string 应该有助于解决您的问题,如果项目的索引匹配,您也可以使用 SelectedIndex 而不是 SelectedItem.

For your new question, your Quantity is of type int and your picker items are of type string, changing Quantity type to string should help solving your issue, you can also use SelectedIndex instead of SelectedItem if the index of the items are matching.

<Picker SelectedIndex="{Binding Quantity, Mode=TwoWay}">
    <Picker.Items>
        <x:String>0</x:String>
        <x:String>1</x:String>
        <x:String>2</x:String>
        <x:String>3</x:String>
        <x:String>4</x:String>
        <x:String>5</x:String>
        <x:String>6</x:String>
    </Picker.Items>
</Picker>

这篇关于xamarin 表单 - 与选择器的双向绑定 - 为什么我不能从后面的代码更新选择器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆