I'm using a DataGridView to display string values using a string wrapper class, a BindingSource and a BindingList.
When launching the app, however, the values are only visible after clicking on the rows. I already tried to look in all possible style property to see where the initial black color comes from, without success.
Initial look:
After clicking (funny colors to try to understand which style does what) or minimizing and maximizing the window:
Form code (already tried some variants here, final version will not look like this):
private BindingSource dataSource;
private BindingList<StringValue> bindingList;
private List<StringValue> list = new List<StringValue>();
public MainForm()
{
InitializeComponent();
grdCodes.AutoGenerateColumns = false;
bindingList = new BindingList<StringValue>(list);
dataSource = new BindingSource(bindingList, null);
grdCodes.DataSource = dataSource;
// Load += MainForm_Load;
x();
}
//private void MainForm_Load(object sender, EventArgs e)
//{
// grdSupiCodes.AutoGenerateColumns = false;
// bindingList = new BindingList<StringValue>(list);
// dataSource = new BindingSource(bindingList, null);
// grdSupiCodes.DataSource = dataSource;
//}
private void x()
{
list.Add(new StringValue("AAAAAAAAAAAA"));
list.Add(new StringValue("BBBBBBBBBBBB"));
list.Add(new StringValue("CCCCCCCCCCCC"));
// none of the below work:
grdCodes.ResetBindings();
// grdCodes.Update();
// grdCodes.Refresh();
// grdCodes.DataSource = null;
// grdCodes.DataSource = dataSource;
}
My question is, how to make the app launch already displaying the values in the grid? I can post the designer code if it helps, but there is nowhere a black color defined (form background is DarkGrey
, visible under the grid).
Given the scenario described:
List<class>
(INotifyPropertyChanged
is most probably not implemented) is added to a BindingList of the same type.Some new Items are added to the List afterwards.
In this scenario, it's simple to verify that the BindingSource doesn't receive any ListChanged events just subscribing to the event: the event is never raised.
Bindinglist.Count
property is incremented to the number of items added, this count is only reporting the number of items contained in the source List<class>
, which doesn't notify changes.IndexOutOfRangeException
is raised, since we're trying to access a non synchronized Item from the internal Dictionary, accessing an Item at index -1
, in practice.Several methods can be used to synchronize the internal collections:
Adding the new Items directly to the BindingList instead of the source List<class>
: the BindingList will generated ListChanged
events in the linked BindingSource, synchronizing the collections and the source List<class>
will be updated anyway.
bindingList.Add(new StringValue("StringValue1"));
bindingList.Add(new StringValue("StringValue2"));
bindingList.Add(new StringValue("StringValue3"));
If new Items need to be added to the original List<class>
, for some reason, call the BindingList.ResetBinding()
or the BindingSource.ResetBinding(false)
methods after the new Items have been added; this will generate the ListChanged
event and the synchronization will be performed as a consequence:
list.Add(new StringValue("StringValue1"));
list.Add(new StringValue("StringValue2"));
list.Add(new StringValue("StringValue3"));
bindingList.ResetBindings();
// Or...
// bindingSource.ResetBinding(false);
Instead of using the BindingList<class>
object directly as the DataSource of the BindingSource, we can set the DataSource to the corresponding Type, so the DataGridView will bind its Columns to the data source using either the DataPropertyName
property, if AutoGenerateColumns = false
, or generate Columns from the source object(s) Properties Names, when AutoGenerateColumns = true
:
BindingList bindingList = new BindingList<StringValue>(list);
BindingSource bindingSource = new BindingSource(typeof(BindingList<StringValue>), null);
dataGridView.DataSource = bindingSource;
After the new Items have been added to the source List<class>
, set the DataSource of the BindingSource to the BindingList, causing the internal collection to re-synchronize:
list.Add(new StringValue("StringValue1"));
list.Add(new StringValue("StringValue2"));
list.Add(new StringValue("StringValue3"));
bindingSource.DataSource = bindingList;