In page we'll explain how to use an DataGridView in your application. How to populate it with data and how to save and retrieve the data from Settings Group.
In this example we use the source code of Project Anonymizer plugin. More information about this plugin can be found here.The plugin code is open source on our Git Hub repository it can be found here.
In other words we want to achieve this:
First step is to drag&drop a DataGridView
control from Toolbox
into our Control Page.
Please make sure the control page implements ISettingsAware<> interface. Next we'll override OnLoad() method;
In the above code we set AutoGenerateColumns=false because we want to create the columns manually. We created an TextBoxColumn and add it to grid columns. "DataPropertyName" is used to bind the content of the cell with the property named "Pattern" set on DataSource.
We'll bind a collection to DataSource property on the grid and all the operations we made on the grid like remove, edit, add we'll do on that collection and the grid will be updated automatically.
Why we use a BindingList<> and not List<> ?
1. The main reason we use it to data bind is that it implements the IRaiseItemChangedEvents interface. That means every time the collection has changed the data grid is automatically refreshed. We don't need to reload the grid explicit, or to go on a specific row index and remove that row or edit it.
2. If AllowUserToAddRow property is set to true,an empty row will appear at the end of the grid. In that row the user can fill the data and automatically an empty row will appear bellow.
How to tie the list used as data source with Batch Task Settings
In the previous page we mention a class which inherits from Settings Group class. In that class you need to store properties for each controls you have on the UI. For example the list used in the data source, or if you have a checkbox there you'll have a property which will be used to set the value on Settings. Later you can retrieve the value an initialize the checkbox with the value saved.
Below is an example on how we set the binding list to Settings:
But this step is not enough. We need to override GetDefaultValue() method.
What does GetDefaultValue() do?
This method is called automatically then you get or set a value to Settings Group. Because in our example we use a list we need to initialize it before we can use it. If we don't add the above code when we retrieve the RegexPattern from the settings it will be null.
After we set the list on Settings Group we want to populate the data grid with the expressions already saved on the settings. On order to do it we'll go back on User Control and add the following code:
This method should be called from OnLoad() method
In SetSettings method is shown how to use SettingsBinder class to get the value from Settings and assign it for example to a text box "Text" property defined on the UI.
How to handle Edit on Data Grid View
Bellow code shows how to handle delete on data grid. We subscribed on KeyDown event.
Code above check if the key pressed is "Delete", it takes all the rows selected and using row.DataBoundItem object we get the corresponding object from the source and removes it from the RegexPatterns list.
In the beginning of the documentation we mentioned that we use BindingList because it raises events when the collections is changed. This works as a charm in a simple Windows Forms application but because our plugin uses Studio Api's the default functionality is overwritten by the API's.
If you subscribe to DataSourceChanged event on grid and put a break point you'll see that the event is not fired even you make a change to your data source collection.
Why this thing happens?
In Visual Studio if you select SettingsGroup and hit F12 you'll see this class implements following interfaces ISettingsGroup, INotifyPropertyChanged, IEditableObject. Because we inherits SettingsGroup class the normal behavior of BindingList is overwritten.
In our Settings Class we added GetDefaultValue() method. This method is fired every time when an object which inherits Settings Group has changed. So to reload automatically the interface we need to assign back the updated list to Settings object like this Settings.RegexPatterns = RegexPatterns, this will fire GetDefaultMethod() and our grid will be refreshed.