0

i m trying to do a project with mvvm xamarin.

I have a listview ( bounded a observablecollection), and inside the listview, i have a button. with clicking this button, i make some updates in Observable collection. But the updates, doesnt effect untill i remove and again insert the Observable collection.

here is the code


 <ListView ItemsSource="{Binding SalesList,Mode=TwoWay}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell IsEnabled="True"    >

                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>


                            <Label FontSize="Large" Text="{Binding StockTotal}"/>

                            <Button Text="+"     Grid.Column="1"  CommandParameter="{Binding .}"   Command="{Binding Path=BindingContext.ADDOPERATION,    Source={x:Reference Mypage}}"  />

                            <Entry Text="{Binding StockAmount}"  Grid.Column="2" />

                        </Grid> 
                    </ViewCell>
                </DataTemplate>  
            </ListView.ItemTemplate> 
        </ListView>

    <Label Text="{Binding SUMMARY}"/>




 public ICommand ADDOPERATION { get; set; }
        public HomeVM()
        {

            SalesList.Add(new SalesModel { StockAmount = 1 });
            SalesList.Add(new SalesModel { StockAmount = 2 });
            SalesList.Add(new SalesModel { StockAmount = 3 });

            ADDOPERATION = new Command(MYADDOPERATION);
        }
        private void MYADDOPERATION(object obj)
        {
            if (obj == null) return;

            var cominginfo = (SalesModel)obj;


            var index= SalesList.IndexOf(cominginfo);


            cominginfo.StockAmount++;

            cominginfo.StockTotal = cominginfo.StockAmount * 55;

 }


 private double _SUMMARY; 
        public double SUMMARY
        {
            get { return SalesList.Sum(c => c.StockTotal); }
            set
            {
                _SUMMARY = SalesList.Sum(c=>c.StockTotal);
                INotifyPropertyChanged();
            }
        }

I don't know why this problem is occured. the ADDOPERATION command works successfuly ( i checked it in debuge mode), but it doesnt update the listview. List view updates when i add this code to below. But i think i m missing something, because, when ever i make changes inside the ObservableCollection, it should automaticly effect the UI. I m able to do it only after i remove and again insert the same data.

            SalesList.RemoveAt(index);

            SalesList.Insert(index, cominginfo); 

the BaseViewModel class for INotifyPropertyChanged event

  public class BaseViewModel : INotifyPropertyChanged
    { 
        public event PropertyChangedEventHandler PropertyChanged;
        protected void INotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

my model class

 public class SalesModel:BaseViewModel
    {

        public double StockTotal { get; set; } 
        public string StockName { get; set; }
        public double StockAmount { get; set; }
    }

Thanks in advance

Fethullah Kaya
  • 194
  • 4
  • 16
  • 1
    `SalesModel` needs to implement INotifyPropertyChanged. ObservableCollection only handles additions and changes to the collection, not changes to properties of items that are in the collection. – Jason Mar 19 '20 at 14:30
  • 1
    See this SO Post about [ObservableCollection not noticing when Item in it changes (even with INotifyPropertyChanged)](https://stackoverflow.com/questions/1427471/observablecollection-not-noticing-when-item-in-it-changes-even-with-inotifyprop), in resume: Observable collection only notifies when an item is added, removed, moved, but not when an item changes, so you need to implement the property change on your Collection Properties – Ricardo Dias Morais Mar 19 '20 at 14:31
  • You can also set ItemSource to null and then back to new Values, but its not ideal. – Woj Mar 19 '20 at 15:41
  • @RicardoDiasMorais i tried , but i could not handle the changed items with the TrulyObservableCollection and other classes. I dont know what to do. – Fethullah Kaya Mar 19 '20 at 19:19
  • @Jason I tried to edit my SalesModel. private double _StockAmount; public double StockAmount { get { return _StockAmount; } set { _StockAmount = value; INotifyPropertyChanged(); } } whit this encapsulation, my app doesnt work. it crashes. – Fethullah Kaya Mar 19 '20 at 19:21
  • That is not how INPC works - see https://stackoverflow.com/questions/1315621/implementing-inotifypropertychanged-does-a-better-way-exist – Jason Mar 19 '20 at 20:11
  • @Jason I already use this class for INotifyPropertyChanged(); I m new on c#. could you help me with the codes if the below code is wrong. thanks public event PropertyChangedEventHandler PropertyChanged; protected void INotifyPropertyChanged([CallerMemberName] string propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } – Fethullah Kaya Mar 19 '20 at 20:28
  • 1
    please edit your question to include any relevant code instead of stuffing it into a comment – Jason Mar 19 '20 at 20:30
  • @Jason i edited. – Fethullah Kaya Mar 19 '20 at 20:35
  • 1
    does SalesModel inherit BaseViewModel? – Jason Mar 19 '20 at 20:37
  • @Jason yes. i edited code again. – Fethullah Kaya Mar 19 '20 at 20:39

1 Answers1

1

you need to call PropertyChanged on the setters in order to notify the UI that the value has changed

private double stockTotal;
public double StockTotal 
{ 
  get
  {
    return stockTotal;
  }
  set 
  {
     stockTotal = value;
     PropertyChanged("StockTotal");
  }
}
Jason
  • 86,222
  • 15
  • 131
  • 146
  • It worked. thank you sir. I have just got the idea. best regards. – Fethullah Kaya Mar 19 '20 at 23:03
  • By the way, it only works for only one property. If i add PropertyChanged("StockAmount"); it doesnt work. app crashes. – Fethullah Kaya Mar 19 '20 at 23:48
  • Did you add a backing field for that property? If it crashes you’re doing something wrong. – Jason Mar 19 '20 at 23:50
  • it s okey now thank u sir. On the other hand, i can not get the sum of a specific column. SUMMARY property doesnt update despite the ObservableCollection updates. I updated the code – Fethullah Kaya Mar 20 '20 at 13:39
  • SUMMARY is not a true property, it is computed. So you should raise PropertyChanged("Summary") whenever StockTotal is set. – Jason Mar 20 '20 at 14:36