Using MVC Pattern in WinForms with C#
Three business object - an abstract LibraryItem Class ,a Book class and a journal class , both derives from LibraryItem
//LibraryItem Class
public abstract class LibraryItem
{
public string Title { get; set; }
private static int _nextCallNum = 1000;
public int CallNum { get; private set; }
public int NumCopies { get; set; }
}
//Journal Class
public class Journal : LibraryItem
{
public int Vol { get; set; }
}
//Book Class
public class Book : LibraryItem
{
public string Author { get; set; }
}
//LibraryController Class
public class LibrayController
{
//a List that can hold both books and journals
private List<LibraryItem> items;
//adds a book object to items
public void AddBookItem(string title, int numCopies , string author) {.....}
//adds a journal object to items
public void AddJournal(string title, int vol, int numCopies){}
//returns a List contaning books and journals to the View
public List<LibraryItem> GetAllItems()
{
return items;
}
}
In Win Forms , using a DataGridView to display list of LibraryItems
dataGridViewItems.DataSource = null;
booksbindingSource = new BindingSource();
foreach (LibraryItem anitem in controller.GetAllItems())
{
LibraryItem aLibraryItem = (LibraryItem) anitem;
booksbindingSource.Add(aLibraryItem);
}
dataGridViewItems.DataSource = booksbindingSource;
When adding a book after journal, or a journal after book to the binding source, I get InvalidOperationException Objects added to a BindingSource's list must all be of the same type.
The description is self-explanatory. I need a way to display LibraryItems in a datagrid than can be both books and journals. I only need to display the base class properties(Title, CallNum and NumCopies of LibraryItem) in the datagrid.
If the
DataSource
property ofBindingSource
has not already been set, then the first object added to the list defines the type for the list, and then all items that you want to add to the list, should be of the type of first object, because the internal list must contain homogeneous types as mentioned in documentations.Instead of adding items to
BindingSource
usingAdd
method, set itsDataSource
property to the list which you get from controller:Note
To solve the problem, its enough and recommended to use above method, but to see the affect of setting
DataSource
, you can setDataSource
property totypeof(LibraryItem)
and you will see it also works as expected: