Reputation: 21147
I'm working on a small WPF application in which I have a combobox that is bound to an ObservableCollection in the code behind:
public Molecule CurrentMolecule { get; set; }
public ObservableCollection<string> Formulas { get; set; }
public MainWindow()
{
CurrentMolecule = new Molecule();
Formulas = new ObservableCollection<string>(CurrentMolecule.FormulasList.ToList());
DataContext = this;
InitializeComponent();
}
<ComboBox x:Name="cmbFormula" ItemsSource="{Binding Path=Formulas}" SelectionChanged="cmbFormula_SelectionChanged"/>
This works fine to populate my combo box with the CurrentMolecule.FormulasList
however if at some point I set CurrentMolecule
to a new instance of Molecule the databinding no longer works. Do I need to implement some kind of OnPropertyChanged event so that no matter what the contents of the combo box will stay current with the CurrentMolecule.FormulasList
?
Upvotes: 0
Views: 76
Reputation: 4109
You have to implement INotifyPropertyChanged
, only then the changes will be updated in UI.
Here are the modifications that I've done to your code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Molecule _CurrentMolecule;
public Molecule CurrentMolecule
{
get
{
return _CurrentMolecule;
}
set
{
_CurrentMolecule = value;
OnPropertyChanged("CurrentMolecule");
Formulas = new ObservableCollection<string>(CurrentMolecule.FormulasList.ToList());
}
}
private ObservableCollection<string> _Formulas;
public ObservableCollection<string> Formulas
{
get { return _Formulas; }
set
{
_Formulas = value;
OnPropertyChanged("Formulas");
}
}
public MainWindow()
{
InitializeComponent();
CurrentMolecule = new Molecule();
DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
Edit:
A better approach is to create a ViewModel and then bind it to the DataContext of the Window
.
Define a new class called ViewModel
as below. Note you might want to change the namespace
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
public class ViewModel : INotifyPropertyChanged
{
#region Properties
private Molecule _CurrentMolecule;
public Molecule CurrentMolecule
{
get
{
return _CurrentMolecule;
}
set
{
_CurrentMolecule = value;
OnPropertyChanged("CurrentMolecule");
Formulas = new ObservableCollection<string>(CurrentMolecule.FormulasList.ToList());
}
}
private ObservableCollection<string> _Formulas;
public ObservableCollection<string> Formulas
{
get { return _Formulas; }
set
{
_Formulas = value;
OnPropertyChanged("Formulas");
}
}
#endregion
#region Constructor
public ViewModel()
{
CurrentMolecule = new Molecule();
}
#endregion
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
Modify the MainWindow
code behind file as below
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
Upvotes: 2
Reputation: 4895
You are probably missing WPF controls datacontext fundamentals. If you are using binding like {Binding CurrentMolecule.FormulasList} or parent controls datacontext is bound to "CurrentMolecule" whenever you swap DataContext of that item, the binding will reset. If you would like to keep the datacontext bound to the FormulasList even when the parent datacontext changes. You need to bind that context directly to FormulasList property and make sure that other parent controls are not using CurrentMolecule as a datacontext, even when its instance changes in your ViewModel.
Upvotes: 0