Here are the things that I can share about your questions:
Databinding in DataGridView vs ListBox
Both DataGridView and ListBox are expected to show a list of data items. But DataGridView have multiple columns, while ListBox is a single list of data. Imagine a List<Person>
; you can show it in ListBox, but you need to determine which property of the Person should be displayed in the ListBox, otherwise what you can see in the list, will be what is returned by Person.ToString()
which is usually the type name, unless you override and return a meaningful string. When you bind the same List<Person>
to DataGridView, if you haven't setup DataGridView to show specific columns, it automatically shows all the properties, and for each property, it shows the string representation of the property. For example if there's a Children
property which is a List<Person>
again, then you will see the string representation of it which is typically the type name. But both controls provide good mechanism for displaying data properly, including CellFormatting
event of DataGridView
, or many other mechanisms. For example, you can take a look at Show Properties of a Navigation Property in DataGridView (Second Level Properties).
So here are the highlights for your first question:
- Always the string representations of the properties will be used for them, no matter if the property is a simple type (int, string, bool) or a complex type (Person, Product), or a list (like List<Person>, Produc[]) which follows the same rule as complex types. It's
ToString()
method of the type which will be used to display it. - If you want to change the string representation, you need to override the
ToString()
method, or use the features of the control. For example, in ListBox, you can determine what property should be used to show data in the list, usingDisplayMember
, or you can useFormat
event to format the data to display. Same applies to DataGridView, where you can determine what properties to display, or useCellFormatting
event to format display data. Or for both controls you can format data before using in data binding, just for example using a Linq query. - Both controls can show a list of data which is an IList, IBindingList, ITypedList, etc. For IEnumerable, you need to use a BindingSource (yes, different from BindingList).
BindingList, INotifyPropertyChanges an seeing the updates
In Windows Forms, in a scenario that you want to see changes of data source in the bound list control, like ComboBox
, ListBox
or DataGridView
(complex two-way data binding), you should use a class that implements IBindingList
interface as DataSource
of data binding. The most suitable implementation is BindingList<T>
. This way each add/remove in the underlying data source of your control will be visible in the control immediately.
Please keep in mind, using BindingList<T>
allows the bound control see added or removed items, but to see also property changes immediately, T
should implement INotifyPropertyChanged
. This way your your controls will be notified of PropertyChanged
and always show fresh data.
DataTable is the only data structure ready to use which has implemented both IBindingList and INotifyPropertyChanged. For more information, take a look at my post here: Databinding to List - See changes of data source in ListBox, ComboBox
As a highlight for your second question:
- In two-way databinding, if you want to see changes of the properties, INotifyPropertyChanges in neccesary. The name tells the story; it notifies the changes in properties and this is how the BinsingList can raise
ListChanged
event for properties as well; otherwise it only raises the event when an item is added or removed. - BindingList, basically raises
ListChanged
event, which helps the UI control to consume the event and show the changes immediately in the control. As I mentioned in previous bullet point, creation, removal events are automatically there, because the BindingList owns the items and knows when it's added or removed so it knows when to raise the ListChanged in case of add or remove. But for modifications, it's properties of the items which are changed, and they are responsible to notify the binding list about the change, and then the BindingList raises the ListChanged event for property modifications as well.
So, no bug; all expected and documented well.
More information:
Take a look at following resources: