Reputation: 29
I have WPF application with Combobox and Button. After I enter value into textbox and press button, the value from textbox should appear in updated list of combobox. I am trying to achieve this with MVVM and binding to combobox. Here is part of code from ViewModel.
public class ViewModel:INotifyPropertyChanged
{
DomainLogic dl = new DomainLogic();
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<string> expenseCategories = new ObservableCollection<string>();
public ObservableCollection<string> ExpenseCategories
{
get
{
return expenseCategories;
}
set
{
expenseCategories = value;
OnPropertyChanged("ExpenseCategories");
}
}
public ViewModel()
{
expenseCategories = new ObservableCollection<string>(dl.GetExpenseCategories());
}
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
Also I am using EF to access DB and DomainLogic class has a method to list all Expense Categories.
Here is code-behind from window:
DomainLogic dl = new DomainLogic();
public Window1()
{
InitializeComponent();
DataContext = new ViewModel();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(textBox.Text))
{
dl.CreateNewExpenseCategory(textBox.Text);
}
else
{
MessageBox.Show("Enter category!");
}
}
Here is also XAML:
<ComboBox x:Name="ExpCategory" HorizontalAlignment="Left" Margin="72,50,0,0" VerticalAlignment="Top" Width="130" ItemsSource="{Binding ExpenseCategories, UpdateSourceTrigger=PropertyChanged}" />
When I add the new category the combobox isn't updated. I'm new to the whole MVVM pattern and I think I'm missing something here.
//EDIT
public void CreateNewExpenseCategory(string name)
{
using (var context = new ExpenseEntities())
{
ExpenseCategory category = new ExpenseCategory() { CategoryName = name};
context.ExpenseCategory.Add(category);
context.SaveChanges();
}
}
Upvotes: 2
Views: 1109
Reputation: 1864
The problem is that CollectionChanged
event doesn't fire.
You are adding a new element inside your DataContext, but you aren't updating your local view of data.
Once you update the DataContext you should refresh your ObservableCollection
or use Local.
Here how you could use Local
:
public ViewModel()
{
expenseCategories = dl.GetExpenseCategories().Local;
}
So you can directly do:
expenseCategories.Add(new ExpenseCategory() {textBox.Text});
dl.GetContext().SaveChanges();
Or you have to update the ObservableCollection
:
dl.CreateNewExpenseCategory(textBox.Text);
// Update your ViewModel ObservableCollection.
However i think that you should use a Command
and not an Event so you can update the ObservableCollection
directly inside the ViewModel.
Example:
using Prism.Commands;
//Other usings
public class ViewModel : INotifyPropertyChanged
{
// Your class methods and properties
public DelegateCommand<string> AddNewExpenseCategory
{
get
{
return new DelegateCommand<string>(Execute_AddNewExpenseCategory);
}
}
public void Execute_AddNewExpenseCategory(string param)
{
expenseCategories.Add(new ExpenseCategory() { param });
dl.GetContext().SaveChanges();
}
Upvotes: 2