ObservableCollection<T> is a generic collection added as part of WPF and Silverlight. WinForms has BindingList<T>. So writing code that targets both WinForms and WPF would mean using BindingList<T> (the common thing) and writing code targetting WPF and Silverlight would mean ObservableCollection<T>. So there would be no way to write code that targets all three platforms. Luckily now (in .NET 4) we can use ObservableCollection<T> anywhere because Microsoft made it part of System.dll. Nice! Two others were also moved here: ReadOnlyObservableCollection<T> and INotifyCollectionChanged.
To double check if I could use these collections outside WPF projects I created a simple console application using them:
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: ObservableCollection<string> noWpf = new ObservableCollection<string> { "Hello", "World" };
6: INotifyCollectionChanged watchCollection = noWpf as INotifyCollectionChanged;
7:
8:
9:
10: if (watchCollection != null)
11: {
12: watchCollection.CollectionChanged += (sender, e) => { Console.WriteLine("Collection action = {0}", e.Action); };
13: }
14:
15: noWpf.Add("Love it!");
16: }
17: }
Compiles. Runs.
Could I use it in WinForms? So I created a simple WinForms application like this:
1: public partial class Form1 : Form
2: {
3: ObservableCollection<string> noWpf;
4:
5: public Form1()
6: {
7: InitializeComponent();
8:
9: noWpf = new ObservableCollection<string> { "Hello", "World" };
10: var bs = new BindingSource() { DataSource = noWpf };
11: bs.ListChanged += (sender, e) => { MessageBox.Show(e.ListChangedType.ToString()); };
12: listBox1.DataSource = bs;
13: }
14:
15: private void button1_Click(object sender, EventArgs e)
16: {
17: noWpf.Add("Test");
18: }
19: }
But when I click the button, which adds a new element to the observable collection, the listbox doesn’t update. It looks like winforms databinding doesn’t support ObservableCollection…