Xamarin Label not updating after initial in Mvvm listview

VipinKrishnaVipinKrishna Member ✭✭
edited December 2018 in Xamarin.Forms

I have 2 listviews in my page. First list shows categories horizontally. Second list shows corresponding products below upon clicking category. Each list item of second list contains plus and minus buttons to add product to the cart. Label updates the count of each product upon clicking buttons.Works perfect for the first time. label is not updating in ui after coming from other category.Button clicks are working, While debugging, label value is updated correctly in viewmodel but not reflected in ui since second time.Need help..

<ListView  x:Name="pdt_list" HasUnevenRows="True" SeparatorVisibility="None" ItemsSource="{Binding Productlist}" BackgroundColor="White" Margin="0,10,0,0" >
            <ListView.ItemTemplate>
                <DataTemplate >
                    <ViewCell >
                        <ViewCell.View>
                             <Frame HasShadow="False" Margin=" 0,10,0,10"  Padding="10,5,10,5" BackgroundColor="#e9e9e9" HeightRequest="80" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand" >
                                  <Grid>
                                            <!--<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"  Margin="0,10,0,10"  >-->

                                  <StackLayout VerticalOptions="FillAndExpand" Margin="0" Padding="10,0,0,0" Orientation="Horizontal" Opacity="{Binding opacity}">

                                     <Image Source="{Binding image}"  Aspect="AspectFill"  WidthRequest="70" HeightRequest="180"  VerticalOptions="FillAndExpand" />

                                      <StackLayout HorizontalOptions="FillAndExpand" Orientation="Vertical"  >

                                        <Label Text="{Binding product_name}" Font="Bold" VerticalTextAlignment="Center" FontSize="Medium" TextColor="Black" FontFamily="opensans_light.ttf#opensans_light" Margin="10,20,0,0" />
                                            <StackLayout Orientation="Horizontal" Margin="10,0,0,0" HorizontalOptions="Start" VerticalOptions="Start"  >
                                                        <Label Text="{Binding rupee}"  TextColor="#FA2E27" HeightRequest="90" 
                                                            FontSize="Medium" HorizontalOptions="Start" VerticalTextAlignment="Start" VerticalOptions="FillAndExpand" />
                                                        <Label Text="{Binding selling_price}" Font="Bold"  HorizontalOptions="Start" Margin="0" TextColor="#FA2E27" VerticalTextAlignment="Start" FontSize="Medium" FontFamily="opensans_light.ttf#opensans_light" />

                                           </StackLayout>
                                      </StackLayout>
                                      <ImageButton Source="carts.png" BackgroundColor="Transparent" IsVisible="False" HorizontalOptions="EndAndExpand" WidthRequest="40" HeightRequest="40" VerticalOptions="CenterAndExpand"  Clicked="Add_cart_Clicked" Margin="0,20,0,0" Aspect="AspectFit" />


                                    <StackLayout Orientation="Horizontal" BackgroundColor="Transparent"   HorizontalOptions="EndAndExpand">
                                        <ImageButton Source="minus.png" HorizontalOptions="EndAndExpand"   BackgroundColor="Transparent"  WidthRequest="25" HeightRequest="25" Clicked="Minus_Tapped" />
  //this label is not updating          <Label Text="{Binding Num}" VerticalTextAlignment="Center" HorizontalOptions="EndAndExpand"   FontSize="Medium" TextColor="Black" FontFamily="opensans_light.ttf#opensans_light" Margin="0,0,0,0" /> 
                                        <ImageButton Source="plus2.png" HorizontalOptions="EndAndExpand"   BackgroundColor="Transparent"   WidthRequest="25" HeightRequest="25"  Clicked="Plus_Tapped"   />
                                    </StackLayout>
                                            </StackLayout>

                                            <StackLayout BackgroundColor="Black" HorizontalOptions="EndAndExpand" VerticalOptions="StartAndExpand" WidthRequest="100" HeightRequest="25" IsVisible="{Binding opaque}" Margin="0,0,0,0" >

                                                <Label Text="Not Available" FontFamily="opensans_light.ttf#opensans_light" TextColor="White" FontAttributes="Bold" HorizontalOptions="Center" VerticalTextAlignment="Center" />
                                            </StackLayout>
                                  </Grid>
                             </Frame>
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

viewmodel:

After clicking plus button, this code is executed:

public ObservableCollection<Product_Value2> purchaselist = new ObservableCollection<Product_Value2>();

public void Plus_item(Product_Value2 product_Value2)
    {
        var list = new ObservableCollection<Product_Value2>(purchaselist);


        string id = product_Value2.id;
        ProductsRegister reg = new ProductsRegister();

        reg.Name_Product = product_Value2.product_name;
        App.Database.SaveProducts(reg);



        if ((purchaselist.ToList() != null) && (purchaselist.ToList().Any()))
        {
            //  bool alreadyExists = purchaselist.Any(x => x.id.Equals(id));
            if (purchaselist.Any(x => x.id.Equals(id)))
            {
                foreach (Product_Value2 pdt in list)
                {
                    if (pdt.id.Equals(id))
                    {
                        pdt.Num++; // here value is updating everytime,but first time only in ui
                OnPropertyChanged("Num");

                    }

                }
            }



        }



        DependencyService.Get<IToast>().ShortAlert("Added To Cart");

        Number++;
        OnPropertyChanged("Number");

    }

Model:

public class Product_Value2 : INotifyPropertyChanged
    {         
        public string id { get; set; }
        public string image { get; set; }
        public string imagepath { get; set; }
        public string product_name { get; set; }
        public string rupee { get; set; }
        public float selling_price { get; set; }
        public float price { get; set; }
        public string available_qty { get; set; }
        public string count { get; set; }        
        public bool minus_enb { get; set; }
        public bool plus_enb { get; set; }


        bool Visibility;
        public bool visibility
        {
            set
            {
                Visibility = value;
                OnPropertyChanged("visibility");
            }
            get
            {
                return Visibility;
            }
        }

        long num1 ;
        public long Num  //this is the label text
        {
            set
            {
                num1 = value;
                OnPropertyChanged("Num");
            }
            get
            {
                return num1;
            }
        }


        bool Visible;
        public bool visible
        {
            set
            {
                Visible = value;
                OnPropertyChanged("visible");
            }
            get
            {
                return Visible;
            }
        }




        void OnPropertyChanged(string IsVisible)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(IsVisible));
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }

Attaching the screenshot below: first time;

second time;

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Odd thing 1: Not sure why you have this:

            void OnPropertyChanged(string IsVisible)
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(IsVisible));
            }
            public event PropertyChangedEventHandler PropertyChanged;
    

    Might be affecting something.

    public class Product_Value2 : INotifyPropertyChanged
    Personally if you just inherit from BindableObject then you get all the binding and notification infrastructure automatically.

    Odd thing 2: You have two similarly but not conventionally named bools for the same thing. Visibility and 'Visible. Normal naming conventions for a bool property would make that IsVisibile because its reads well if (IsVisible) DoThisMethod();`
    Sticking with established naming conventions will help keep you from being that guy at work and pissing off your team mates or having your code sent back to you when it comes time for code reviews.

    Odd thing 3: Another naming and type problem
    public string available_qty { get; set; }
    Quantities aren't strings. This should be an int since quantities are generally positive whole values.

    Odd thing 4: More confusing similar names

            public string image { get; set; }
            public string imagepath { get; set; }
    

    There is already a type of Image - don't make properties that so closely mimick type names.
    How is it you need two properties for the same thing? ImagePath covers it.

    And again with Price

            public float selling_price { get; set; }
            public float price { get; set; }
    

    Even the class name public class Product_Value2 - THis is more than just the value of a product. It is the product considering its got a name, quantity, cost etc. By the way... The Product itself wouldn't hold the AvailableQuantity of its own kind. Its not the responsibility of a thing to know how many of its own kind are in inventory. Every car on the sales lot doesn't know there are 200 other cars.

    You're really going out of your way to make similar, excessive and confusing properties. If people on our team did that we'd be really pissed off at them.

    Two bits of advice:
    1. Clean up your code and naming practices so team members can follow what you're doing. Use meaningful names.
    2. Slow down. Design your app, your objects and your logic before you start banging on the keyboard. It really looks like you're in such a hurry to get some code down... any code... that you've not bothered to plan so you can make good code.

    Here's a tutorial series that may help you with understanding binding - which after all is the reason for your question: Your binding is bad and doesn't work as expected.
    http://redpillxamarin.com/2018/03/12/2018-101-vs2017-new-solution/

  • VipinKrishnaVipinKrishna Member ✭✭

    made some changes. working fine..

    if (purchaselist.Any(x => x.id.Equals(id)))
                    {
                        foreach (Product_Value2 pdt in list)
                        {
                            if (pdt.id.Equals(id))
                            {
                                pdt.Num++; // here value is updating everytime,but first time only in ui
                                product_Value2.Num  = pdt.Num; 
    
    
                            }
    
                        }
                    }
    
  • VipinKrishnaVipinKrishna Member ✭✭
    edited December 2018

    @ClintStLaurent

    thank u sir for the knowledge. I'm a xamarin beginner.i would definitely follw your answer...

Sign In or Register to comment.