frankiehf frankiehf - 2 months ago 91
C# Question

DataGridView Masked TextBox Column

I have a DataGridView with 2 columns,and i wanted to create some kind of input mask to it. So i found a small class that inherits maskedtextbox control and lets you use it in a datagridview. Everything works fine,the mask works as intended, no big deal. heres the library: http://www.codeproject.com/Articles/26005/DataGridViewColumn-Hosting-MaskedTextBox

My problem is,once the row has all the data i need,pressing enter or tab does not create a new row, even tho i have datagridview1.AllowUserToAddRows = true.
Then i found out the problem was in the library i linked,because when i add a simple datagrid textbox,pressing enter or tab does create a new row.

so i added this routine,to hopefully create a new row when i am on the last column of the last row:

private void dgOre_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if(e.RowIndex== dgOre.Rows.Count-1 && e.ColumnIndex== dgOre.Columns.Count - 1){
dgOre.Rows.Add();
}
}


the problem with this routine is that it does add a row,but it creates it BEFORE the last row,creating a gap,as if i am creating a row before some other event is launched. I should change something in the maskedtextbox library, or use a different event,but i have no idea how and what to edit.

Here is the source code of editing control:

public class DataGridViewMaskedTextEditingControl : MaskedTextBox,
IDataGridViewEditingControl
{
#region Fields
private DataGridView dataGridView;
private bool valueChanged;
private int rowIndex;
#endregion
#region Constructor
public DataGridViewMaskedTextEditingControl()
{
Mask = String.Empty;
}
#endregion
#region Interface's properties
public DataGridView EditingControlDataGridView
{
get { return dataGridView; }
set { dataGridView = value; }
}
public object EditingControlFormattedValue
{
get { return Text; }
set
{
if (value is string)
Text = (string)value;
}
}
public int EditingControlRowIndex
{
get { return rowIndex; }
set { rowIndex = value; }
}
public bool EditingControlValueChanged
{
get { return valueChanged; }
set { valueChanged = value; }
}
public Cursor EditingPanelCursor
{
get { return base.Cursor; }
}
public bool RepositionEditingControlOnValueChange
{
get { return false; }
}

#endregion
#region Interface's methods
public void ApplyCellStyleToEditingControl(
DataGridViewCellStyle dataGridViewCellStyle)
{
Font = dataGridViewCellStyle.Font;
// get the current cell to use the specific mask string
DataGridViewMaskedTextCell cell
= dataGridView.CurrentCell as DataGridViewMaskedTextCell;
if (cell != null)
{
Mask = cell.Mask;
}
}
public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
{
// Note: In a DataGridView, one could prefer to change the row using
// the up/down keys.
switch (key & Keys.KeyCode)
{
case Keys.Left:
case Keys.Right:
case Keys.Home:
case Keys.End:
return true;
default:
return false;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
if (selectAll)
SelectAll();
else
{
SelectionStart = 0;
SelectionLength = 0;
}
}
#endregion
#region MaskedTextBox event
protected override void OnTextChanged(System.EventArgs e)
{
base.OnTextChanged(e);
EditingControlValueChanged = true;
if (EditingControlDataGridView != null)
{
EditingControlDataGridView.CurrentCell.Value = Text;
}
}
#endregion
}

Answer

When a change is made in your editing control, you should notify the grid of changes using NotifyCurrentCellDirty(true) of the grid. So you can write such code in your editing control:

protected override void OnTextChanged(EventArgs e)
{
    base.OnTextChanged(e);
    EditingControlValueChanged = true;
    EditingControlDataGridView.NotifyCurrentCellDirty(true);
}
Comments