Innova
Innova

Reputation: 396

Xamarin: ObservableCollection does't automatically update ListView

I have a ListView bounded to an ObservableCollection in the ViewModel. In initialization the ListView items are displayed perfectly. However, when I try to update a single value of an item of ObservableCollection at run-time, the linked item in the listview does not update automatically. It updates only if I scroll the listView. Why does it behave like this?

Here's the code:

XAML

            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Frame Style="{StaticResource frameListView}" >
                            <StackLayout Margin="-15">

                                <Label Text="{Binding Articolo.Descrizione}"
                                       Style="{StaticResource labelDescrizioneStyle}" />

                                    <StackLayout Orientation="Horizontal"
                                                 HorizontalOptions="End" VerticalOptions="Center">

                                        <Button x:Name="removeButton" 
                                                VerticalOptions="Center" HorizontalOptions="Center"
                                                Text="-"
                                                Font="20"
                                                WidthRequest="45" FontAttributes="Bold"
                                                Style="{StaticResource buttonNeutroStyle}"  
                                                Command="{Binding Source={x:Reference mieiAcquistiStack}, Path=BindingContext.AggiungiCommand}"                                                   
                                                CommandParameter="{Binding .}" />       

                                        <StackLayout HorizontalOptions="FillAndExpand"
                                                     VerticalOptions="FillAndExpand" >

                                            <Label Text="{Binding QtaEdit}" 
                                                   TextColor="Black"
                                                   FontSize="18" FontAttributes="Bold"
                                                   WidthRequest="40"
                                                   HorizontalTextAlignment="Center" VerticalTextAlignment="Center"
                                                   VerticalOptions="FillAndExpand"/>
                                        </StackLayout>

                                        <Button x:Name="addButton" 
                                                VerticalOptions="Center" HorizontalOptions="Center"
                                                Text="+"
                                                WidthRequest="45" FontAttributes="Bold"   
                                                Style="{StaticResource buttonNeutroStyle}"   
                                                Command="{Binding Source={x:Reference mieiAcquistiStack}, Path=BindingContext.AggiungiCommand}"   
                                                CommandParameter="{Binding .}" />
                                    </StackLayout>
                            </StackLayout>
                        </Frame>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>

ViewModel

        public static ObservableCollection<RigaStoricoModel> acquistiList;
        public ObservableCollection<RigaStoricoModel> AcquistiList
        {
            get { return acquistiList; }
            set
            {
                if (acquistiList != value)
                {
                    acquistiList = value;
                    OnPropertyChanged();
                }
            }
        }

        private void AggiungiArticolo(RigaStoricoModel prodotto, ParametriUM parametriUM)
        {
            double esistenzaUMPredef = parametriUM.EsistenzaUMPredef.GetValueOrDefault(0);

            if (esistenzaUMPredef > 0)
            {
                double qtaMinima = parametriUM.QtaMinima.GetValueOrDefault(1);

                if (prodotto.QtaEdit + qtaMinima <= esistenzaUMPredef)
                {
                    prodotto.QtaEdit += qtaMinima;  // <-- here the update not working
                }
            }

Upvotes: 1

Views: 3896

Answers (1)

Leon Lu
Leon Lu

Reputation: 9274

Do you want to achieve the result like following GIF?

enter image description here

If so, you should achieve the INotifyPropertyChanged interface in your RigaStoricoModel as Silvermind's said.

Here is MyViewModel.cs code.

   public class RigaStoricoModel: INotifyPropertyChanged
    {

        private double _qtaEdit;
        public double QtaEdit
        {
            set
            {

                _qtaEdit = value;

                OnPropertyChanged("QtaEdit");

            }
            get => _qtaEdit;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

I used AggiungiCommand to make a test(decrease or increase).

    public class MyViewModel
    {
        public static ObservableCollection<RigaStoricoModel> acquistiList;
        public ObservableCollection<RigaStoricoModel> AcquistiList
        {
            get { return acquistiList; }
            set
            {
                if (acquistiList != value)
                {
                    acquistiList = value;
                  //  OnPropertyChanged();
                }
            }
        }

        public ICommand AggiungiCommand { protected set; get; }
        public ICommand AggiungiCommand2 { protected set; get; }

        //  public int MyProperty { get; set; }

        public MyViewModel()
        {
            AcquistiList = new ObservableCollection<RigaStoricoModel>();
            AcquistiList.Add(new RigaStoricoModel() { QtaEdit=0.28 });
            AcquistiList.Add(new RigaStoricoModel() { QtaEdit = 0.38 });
            AcquistiList.Add(new RigaStoricoModel() { QtaEdit = 0.48 });
            AcquistiList.Add(new RigaStoricoModel() { QtaEdit = 0.58 });
            AcquistiList.Add(new RigaStoricoModel() { QtaEdit = 0.68 });

            AggiungiCommand2=new Command(async (key) =>
            {
                RigaStoricoModel model = key as RigaStoricoModel;
                model.QtaEdit += 0.1;

            });
            AggiungiCommand = new Command(async (key) =>
            {
                RigaStoricoModel  model= key as RigaStoricoModel;
                model.QtaEdit -= 0.1;

            });
        }
    }
}

Here is layout.xaml(I do not have this style, for testing,I delete them and adjust this layout).

    <StackLayout>
        <!-- Place new controls here -->
        <ListView ItemsSource="{Binding AcquistiList}" x:Name="mieiAcquistiStack" HasUnevenRows="True" >

            <ListView.ItemTemplate>
                <DataTemplate> 
                    <ViewCell>
                        <Frame  >
                            <StackLayout Margin="-15" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">

                                <Label Text="{Binding Articolo.Descrizione}"
                                       />

                                <StackLayout Orientation="Horizontal"
                                                 HorizontalOptions="End" VerticalOptions="Center">

                                    <Button x:Name="removeButton" 
                                                VerticalOptions="Center" HorizontalOptions="Center"
                                                Text="-"
                                                Font="20"
                                                WidthRequest="45" FontAttributes="Bold"

                                                Command="{Binding Source={x:Reference mieiAcquistiStack}, Path=BindingContext.AggiungiCommand}"                                                   
                                                CommandParameter="{Binding .}" />

                                    <StackLayout HorizontalOptions="FillAndExpand"
                                                     VerticalOptions="FillAndExpand" >

                                        <Label Text="{Binding QtaEdit}" 
                                                   TextColor="Black"
                                                   FontSize="18" FontAttributes="Bold"
                                                   WidthRequest="40"
                                                   HorizontalTextAlignment="Center" VerticalTextAlignment="Center"
                                                   VerticalOptions="FillAndExpand"/>
                                    </StackLayout>

                                    <Button x:Name="addButton" 
                                                VerticalOptions="Center" HorizontalOptions="Center"
                                                Text="+"
                                                WidthRequest="45" FontAttributes="Bold"   

                                                Command="{Binding Source={x:Reference mieiAcquistiStack}, Path=BindingContext.AggiungiCommand2}"   
                                                CommandParameter="{Binding .}" />
                                </StackLayout>
                            </StackLayout>
                        </Frame>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>

Here is layout background code.

    public MainPage()
        {
            InitializeComponent();

            this.BindingContext = new MyViewModel();
        }

Upvotes: 1

Related Questions