I've created DataGridView in windows forms app with check box and text box.
When I click on checkbox I want some action executed - another button clicked.
I require that editing of row in which click occurred finishes its editing session so that underlying BindingSource is updated to latest change.
So if my click unchecked or checked given field I wish to have it in my underlying DataTable so some other logic can immediately use it.
This proved to bit a bit tricky.
Note that in this scenario Checkboxcolumn in question is expected exactly at columnindex 0.
public EditorGUI()
{
InitializeComponent();
gridTables.CellContentClick += ( o, e ) =>
{
if ( e.ColumnIndex > 0 ) return;
gridTables.CommitEdit( DataGridViewDataErrorContexts.Commit );
};
gridTables.CellValueChanged += ( o, e ) => btnQuicksrch_Click( this, null );
}
Here is second scenario. There are two grids - gridColumns & gridSelFields.
They both reflect same data but filter it in different way.
When user clicks and checks/unchecks checkbox in gridColumns second grid should immediately get updated since they reflect same data.
private delegate void AfterDirtyStateChangedDelegate();
private void MyForm()
...
gridColumns.CurrentCellDirtyStateChanged += gridColumns_CurrentCellDirtyStateChanged;
gridColumns.CellValueChanged += gridColumns_CellValueChanged;
First event to detect click and SPACE on checkbox is CurrentCellDirtyStateChanged:
void gridColumns_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if ((sender as DataGridView).IsCurrentCellDirty)
{
BeginInvoke(new AfterDirtyStateChangedDelegate(DirtyStateChanged));
}
}
If cell "dirty" (change occured) async invoke committing of changes to underlying data list.
private void DirtyStateChanged()
{
Debug.Print("DirtyStateChanged()");
gridColumns.CommitEdit(DataGridViewDataErrorContexts.Commit);
gridColumns.EndEdit();
bindSrcColumns.EndEdit();
}
In DirtyStateChanged all three commits must execute to make sure our change is commited.
Above committing will finally raise CellValueChanged event.
void gridColumns_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
UpdateIsSelectedToSelFields(e);
GridColumnsFieldSelection(e.RowIndex);
}
Only at this point we are sure that binding source of Columns is updated so we can use it.
...
var selField_SelRow_IsSelected = (bindSrcSelFields.DataSource as DataTable).Rows.Find(col_SelRow[EDITORCOLUMN_FIELDNAME])[EDITORCOLUMN_ISSELECTED];
(bindSrcSelFields.DataSource as DataTable).Rows.Find(col_SelRow[EDITORCOLUMN_FIELDNAME])[EDITORCOLUMN_ISSELECTED] = !Convert.ToBoolean(selField_SelRow_IsSelected);
...
Watch it ! In above this DOES NOT work :
selField_SelRow_IsSelected = !Convert.ToBoolean(selField_SelRow_IsSelected);
There is at the moment still active bug with DataGridView. When you press SPACE on checkbox field and handle CellContentClick you get exception.
Here it is explained:
http://connect.microsoft.com/VisualStudio/feedback/details/780347/nullreferenceexception-in-notifymassclient-after-checking-unchecking-a-checkbox-in-datagridview-with-spacebar#details
That's where I got above delegate thing.
There is only one misbehavior with above scenario. When you use SPACE key you cannot check and immediately uncheck same record. After first SPACE leave current row and come back.
This is due to fact that after first SPACE we ended EditMode and only by leaving and getting focus again will enter Edit mode again.
Furthermore consider DataGridView.EditMode
http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(System.Windows.Forms.DataGridView.CellContentClick);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true
No comments:
Post a Comment