问题
I have created a custom DataGridViewColumn for my project in WinForms. The control renders perfectly, but once I input the value and move to another cell, the value disappears and comes up as null when I check in CellEndEdit.
Following is the code:
class NumericEditControl : NumericTextBox, IDataGridViewEditingControl
{
DataGridView dataGridView;
private bool valueChanged = false;
int rowIndex;
public NumericEditControl()
{
this.Value = 0;
}
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
this.ForeColor = dataGridViewCellStyle.ForeColor;
this.BackColor = dataGridViewCellStyle.BackColor;
}
public DataGridView EditingControlDataGridView
{
get
{
return dataGridView;
}
set
{
dataGridView = value;
}
}
public object EditingControlFormattedValue
{
get
{
return this.Value;
}
set
{
this.Value = Convert.ToDouble(value);
}
}
public int EditingControlRowIndex
{
get
{
return rowIndex;
}
set
{
rowIndex = value;
}
}
public bool EditingControlValueChanged
{
get
{
return valueChanged;
}
set
{
valueChanged = value;
}
}
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
switch (keyData & Keys.KeyCode)
{
case Keys.Left:
case Keys.Up:
case Keys.Down:
case Keys.Right:
case Keys.Home:
case Keys.End:
case Keys.PageDown:
case Keys.PageUp:
return true;
default:
return !dataGridViewWantsInputKey;
}
}
public Cursor EditingPanelCursor
{
get
{
return base.Cursor;
}
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return EditingControlFormattedValue;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
}
public bool RepositionEditingControlOnValueChange
{
get { return false; }
}
}
The cell class is as follows:
public class NumericCell : DataGridViewTextBoxCell
{
public NumericCell()
: base()
{
this.Style.Format = "0";
}
public override void InitializeEditingControl(int rowIndex, object
initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue,
dataGridViewCellStyle);
NumericEditControl ctl =
DataGridView.EditingControl as NumericEditControl;
// Use the default row value when Value property is null.
if (this.Value == null)
{
ctl.Value = 0;
}
else
{
ctl.Value = (double)this.Value;
}
}
public override Type EditType
{
get
{
return typeof(NumericEditControl);
}
}
public override Type ValueType
{
get
{
return typeof(double);
}
}
public override object DefaultNewRowValue
{
get
{
return "0";
}
}
}
And finally the DataGridViewColumn
public class NumericDataColumn : DataGridViewColumn
{
public NumericDataColumn()
: base(new NumericCell())
{
}
public override DataGridViewCell CellTemplate
{
get
{
return base.CellTemplate;
}
set
{
if (value != null &&
!value.GetType().IsAssignableFrom(typeof(NumericCell)))
{
throw new InvalidCastException("Must be a Numeric");
}
base.CellTemplate = value;
}
}
}
In the designer
private GridControl.NumericDataColumn colRoll;
It renders the control but I cannot understand why the value is disappearing. Can you please help me out
回答1:
It turns out that we have to handle the control's Text / Value change event as well and until and unless the cell is dirty the value will not retain. So I had to add the following method to my NumericEditControl class
class NumericEditControl : NumericTextBox, IDataGridViewEditingControl
{
//Old code here
protected override void OnTextChanged(EventArgs e)
{
if (dataGridView != null)
{
valueChanged = true;
this.dataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e);
}
}
}
Adding this method saved my life and my control is working properly now :D thanks for the input.
来源:https://stackoverflow.com/questions/35053869/custom-datagridviewcolumn-value-disappears-after-loosing-focus