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();