0

I am trying to refresh the view when I update the values in one of the objects from a list. It works when I update the list itself (add a new item) but not when I update the objects value themselves.

I have the base viewmodel in which I implement INotifyPropertyChanged:

public class BaseViewModel : INotifyPropertyChanged
    {    
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var changed = PropertyChanged;
            if (changed == null)
                return;

            changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }

Then in my ViewModel:

public class SAVSplitViewModel : BaseViewModel
{
    public ObservableCollection<ListItem> Items
    {
        get { return primaryBin.Items; }
        set { primaryBin.Items = value; OnPropertyChanged(); }
    }

    public ObservableCollection<ListItem> CurrentItems
    {
        get 
        {
            if (IsPrimaryBin)
                return primaryBin.Items;
            else
                return secondaryBin.Items;
        }
        set
        {
            if (IsPrimaryBin)
                primaryBin.Items = value;
            else
                secondaryBin.Items = value;
        }
    }

    public ObservableCollection<ListItem> NotCurrentItems
    {
        get
        {
            if (!IsPrimaryBin)
                return primaryBin.Items;
            else
                return secondaryBin.Items;
        }
        set
        {
            if (!IsPrimaryBin)
                primaryBin.Items = value;
            else
                secondaryBin.Items = value;
        }
    }
}

And in my View, when I update the value of one of the ListItem, it does not refresh the view. But it does refresh when I add a new item. What am I doing wrong?

                if (Found) 
                {
                    viewModel.IsBusy = true;

                    //Check if there are already some of this product received
                    ListItem origin = viewModel.CurrentItems.FirstOrDefault(i => i.EAN == labelText);

                    updateErp = false;
                    SupplierOrderLineForScan p = viewModel.lines.FirstOrDefault(pr => pr.Ean.Trim() == labelText.Trim());
                    u = await Common.GetPickingUser();

                    //Check if there is already some of this product on the trolley
                    ListItem bincontentDirection = viewModel.NotCurrentItems.FirstOrDefault(i => i.EAN == labelText);
                    BinContent bincontentOrigin = viewModel.NotCurrentBinContents.Find(s => s.StockId == p.StockId);


                    if (bincontentDirection == default(ListItem))
                    {
                        bincontentDirection = new ListItem { 
                            Quantity = 0
                            , EAN = origin.EAN, Name = origin.Name};
                        viewModel.ItemsTransfer.Add(bincontentDirection);
                    }
                    bincontentDirection.Quantity++;
                    origin.Quantity--;

                }

Edit: updated my model to try and solve the issue. Did not work.

public class BaseModel : INotifyPropertyChanged
{
    protected bool SetProperty<T>(ref T backingStore, T value,
        [CallerMemberName] string propertyName = "",
        Action onChanged = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingStore, value))
            return false;

        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    #region INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;

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

}

public class ListItem : BaseModel
{
    private int _quantity;
    public int Quantity
    {
        get { return _quantity; }
        set { SetProperty(ref _quantity, value); }
    }
}
Elgate
  • 113
  • 2
  • 11
  • That is probably because you are updating a property of the `ListItem` class and not adding or removing anything from the `ObservableCollection`(which would trigger a view refresh). To fix this you need to implement the `INotifyPropertyChanged` interface in your `ListItem` Class as well so the view is also notified when a property of the Item is changed. – CodeJunkie Apr 20 '23 at 09:38
  • It's a common misunderstanding that an ObservableCollection will raise an event if any of the contained items changes a property. The observable part is that you have the CollectionChanged event available that is triggered when the collection updates its items. The NotifyCollectionChangedEventArgs of that event has all the information needed to access the changed items and in turn attach to their PropertyChanged event. You may like to see the discussions here at SO, like https://stackoverflow.com/questions/901921/observablecollection-and-item-propertychanged – ThomasB Apr 20 '23 at 11:43
  • @ThomasB Thanks, I tried doing so following another answer I found, but the result doesn't seem to work. Edited the original message to show the Model as well. https://stackoverflow.com/questions/1859946/c-wpf-propertychanged-for-all-properties-in-viewmodel – Elgate Apr 20 '23 at 13:07

1 Answers1

0

But your are still not using the CollectionChanged event of your CurrentItems or NotCurrentItems ObservableCollections to attach to the PropertyChanged event of the items inside.

ThomasB
  • 161
  • 6