Home > Net >  ListBox does not get updated, even if it's set to ObservableCollection
ListBox does not get updated, even if it's set to ObservableCollection

Time:06-18

I use Prism. Data provider works correctly (SQLite here).

<ListBox ItemsSource="{Binding Path=CategoryList}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}"/>
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

public class ListsViewModel : BindableBase
{
    private readonly IDataProvider _dataProvider;
    private readonly IRegionManager _regionManager;
    public DelegateCommand ClickAddCategory { get; set; }

    private string categoryName;
    public string CategoryName
    {
        get { return categoryName; }
        set { SetProperty(ref categoryName, value); }
    }

    private ObservableCollection<ExtraCategory> categoryList;
    public ObservableCollection<ExtraCategory> CategoryList
    {
        get 
        { 
            if (categoryList == null) return _dataProvider.GetCategoryList();
            else return categoryList; 
        }
        set { SetProperty(ref categoryList, value); }
    }

    public ListsViewModel(IRegionManager regionManager,  IDataProvider dataProvider)
    {
        _dataProvider = dataProvider;
        _regionManager = regionManager;
        ClickAddCategory = new DelegateCommand(ClickedAddCategory);
        //MessageBox.Show("Hello from "   this.ToString());
    }

    private void ClickedAddCategory()
    {
        ExtraCategory newCategoryFromForm = new ExtraCategory(CategoryName);
        CategoryList.Add(newCategoryFromForm);
        _dataProvider.AddCategory(newCategoryFromForm);
    }
}

If I change the line:

CategoryList.Add(newCategoryFromForm);

to

CategoryList = _dataProvider.GetCategoryList();

everything would work fine because code inside set {} will run but that's not a solution. I would really appreciate some help. Also I really don't want to break MVVM pattern.

CodePudding user response:

You want to put an ObservableCollection in a property without setter. And you want the value to stay the same.

private ObservableCollection<ExtraCategory> categoryList;
public ObservableCollection<ExtraCategory> CategoryList
{
    get 
    { 
        if (categoryList == null) return _dataProvider.GetCategoryList();
        else return categoryList; 
    }
    set { SetProperty(ref categoryList, value); }
}

This gives you a new ObservableCollection everytime you call CategoryList.get, i.e. CategoryList.Add(newCategoryFromForm); fetches a new list, adds the new item, then discards the list (returning a value from a property's getter does not magically set a backing field).

I'd do it this way:

public ObservableCollection<ExtraCategory> CategoryList { get; }

and in constructor:

CategoryList = _dataProvider.GetCategoryList();
  • Related