The bindingsource is meant to bind the data to the displayed data. In your case the displayed data is the data grid view.
If you decide to use a binding source as the data source for your DataGridView you shouldn't handle the DataGridView programmatically anymore. Because you told the DataGridView that its DataSource would be your BindingSource, your program should only change the data by changing the data in the DataSource. Once changed, the DataGridview and the BindingSource will take care that the corresponding displayed item is updated.
Similarly if an operator changes the displayed item, the DataGridView and the BindingSource will take care that the corresponding object is updated.
Once the DataSource of a DataGridView is set, you should not change the DataGridView programmatically, but change the data in the DataSource.
You want to display URI strings, the problem is that if it changes, no one gets notified about these changes, so no one can react on the changes. The reason for this is because class string doesn't implement interface INotifyPropertyChanged
So we have to create a class of URI strings to display.
public class MyDisplayableUriString
{
public string UriString {get; set;}
... // if desired other properties
}
We want a form to display the list of MyDisplayableUriString:
- Create a new Windows Forms application
- Add a BindingSource using the Toolbox
- BindingSource properties DataSource = MyDisplayableUriString
- Add a DataGridView using the Toolbox
- DataGridView properties: DataSource = BindingSource1
You should see the fields of MyDisplayableUriString displayed in the DataGridView.
- Use the properties windows to ass an event handler for when the form loads
In this event handler fill the BindingSource with several Displayable URi strings:
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 10; ++i)
{
MyDisplayableUriString uriItem = new MyDisplayableUriString()
{
Uri = "URI " + i.ToString()
};
this.bindingSource1.Add(uriItem);
}
}
If you run the program you should see that the table is filled with the created URI items.
Now let's change one of the items:
Add a button and create a handler for button click:
private void button1_Click(object sender, EventArgs e)
{
MyDisplayableUriString uriItem = (MyDisplayableUriString)this.bindingSource1[0];
uriItem.UriString = "John";
}
Now if you run the program and click the button the name is not updated.
The reason for this is that your class doesn't implement INotifyPropertyChanged. Therefore bindingsource doesn't get notified when an uri item is changed. And thus the DataGridView is not updated.
Luckily StackOverflow has an article about a proper implementation:
Implementing INotifyPropertyChanged
The code is as follows:
public event PropertyChangedEventHandler PropertyChanged;
private string uriName = null;
public string UriName
{
get { return this.uriName; }
set { this.SetField(ref this.uriName, value); }
}
protected void SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
RaiseEventPropertyChanged(propertyName);
}
}
private void RaiseEventPropertyChanged(string propertyName)
{
var tmpEvent = this.PropertyChanged;
if (tmpEvent != null)
{
tmpEvent(this, new PropertyChangedEventArgs(propertyName));
}
}
Now whenever your program changes the object in the bindingsource the display is automatically updated, and if the operator changes the display the items in the bindingsource are updated, and your program get notified about the changes via events