VS2005 CTP July Am I the only developer on the planet that needs to restrict a Datagridview column to numeric input with Minimum, Maximum and decimal places? I have searched high and low. Does anyone have working code that lets you use a NumericUpDown control as a cell in a DataGridView control? This is such a BASIC function for a grid control that I just can't believe that Microsoft does not have it as part of the datagridview control columns. I have tried converting the CalendarCell class in MSDN Magazine/ April 2005 Cutting Edge but I cant get the column to allow input of the decimal point and the NumericUpDown control will only display when you click on it. It will not display in all cells of the column at one time. Imports System Imports System.Windows.Forms #Region "NumericUpDownColumn Class" Public Class NumericUpDownColumn Inherits DataGridViewColumn Public Sub New() MyBase.New(New NumericUpDownCell()) End Sub 'New Public Overrides Property CellTemplate() As DataGridViewCell Get Return MyBase.CellTemplate End Get Set(ByVal value As DataGridViewCell) ' Ensure that the cell used for the template is a NumericUpDownCell If Not (value Is Nothing) And Not value.GetType().IsAssignableFrom(GetType(NumericUpDownCell)) Then Throw New InvalidCastException("Must be a NumericUpDownCell") End If MyBase.CellTemplate = value End Set End Property End Class #End Region #Region "NumericUpDownCell Class" Public Class NumericUpDownCell Inherits DataGridViewTextBoxCell Public Sub New() End Sub Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle) MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle) Dim ctl As NumericUpDownEditingControl = CType(DataGridView.EditingControl, NumericUpDownEditingControl) ctl.Value = CType(Me.Value, Decimal) End Sub Public Overrides ReadOnly Property EditType() As Type Get ' Return the type of the editing contol that NumericUpDownCell uses. Return GetType(NumericUpDownEditingControl) End Get End Property Public Overrides ReadOnly Property ValueType() As Type Get ' Return the type of the value that NumericUpDownCell contains. Return GetType(Decimal) End Get End Property Public Overrides ReadOnly Property DefaultNewRowValue() As Object Get Return 0D End Get End Property End Class #End Region #Region "NumericUpDownEditingControl Class" Class NumericUpDownEditingControl Inherits NumericUpDown Implements IDataGridViewEditingControl Private dataGridViewControl As DataGridView Private valueIsChanged As Boolean = False Private rowIndexNum As Integer Public Sub New() End Sub Public Sub ApplyCellStyleToEditingControl(ByVal dataGridViewCellStyle As System.Windows.Forms.DataGridViewCellStyle) Implements System.Windows.Forms.IDataGridViewEditingControl.ApplyCellStyleToEditingControl Me.Font = dataGridViewCellStyle.Font End Sub Public Property EditingControlDataGridView() As System.Windows.Forms.DataGridView Implements System.Windows.Forms.IDataGridViewEditingControl.EditingControlDataGridView Get Return Me.dataGridViewControl End Get Set(ByVal value As System.Windows.Forms.DataGridView) Me.dataGridViewControl = value End Set End Property Public Property EditingControlFormattedValue() As Object Implements System.Windows.Forms.IDataGridViewEditingControl.EditingControlFormattedValue Get Return Me.Value.ToString End Get Set(ByVal value As Object) If TypeOf value Is [String] Then Me.Value = CType(value, Decimal) End If End Set End Property Public Property EditingControlRowIndex() As Integer Implements System.Windows.Forms.IDataGridViewEditingControl.EditingControlRowIndex Get Return rowIndexNum End Get Set(ByVal value As Integer) rowIndexNum = value End Set End Property Public Property EditingControlValueChanged() As Boolean Implements System.Windows.Forms.IDataGridViewEditingControl.EditingControlValueChanged Get Return valueIsChanged End Get Set(ByVal value As Boolean) valueIsChanged = value End Set End Property Public Function EditingControlWantsInputKey(ByVal key As System.Windows.Forms.Keys, ByVal dataGridViewWantsInputKey As Boolean) As Boolean Implements System.Windows.Forms.IDataGridViewEditingControl.EditingControlWantsInputKey Select Case key And Keys.KeyCode Case Keys.Left, Keys.Up, Keys.Down, Keys.Right, Keys.Home, Keys.End, Keys.PageDown, Keys.PageUp Return True Case Else Return False End Select End Function Public ReadOnly Property EditingPanelCursor() As System.Windows.Forms.Cursor Implements System.Windows.Forms.IDataGridViewEditingControl.EditingPanelCursor Get Return MyBase.Cursor End Get End Property Public Function GetEditingControlFormattedValue(ByVal context As System.Windows.Forms.DataGridViewDataErrorContexts) As Object Implements System.Windows.Forms.IDataGridViewEditingControl.GetEditingControlFormattedValue Return Me.Value.ToString End Function Public Sub PrepareEditingControlForEdit(ByVal selectAll As Boolean) Implements System.Windows.Forms.IDataGridViewEditingControl.PrepareEditingControlForEdit End Sub Public ReadOnly Property RepositionEditingControlOnValueChange() As Boolean Implements System.Windows.Forms.IDataGridViewEditingControl.RepositionEditingControlOnValueChange Get Return False End Get End Property End Class #End Region |
| DrMicrochip Monday, August 29, 2005 8:44 PM |
Unfortunately the DataGridView does not support masked input out of the box. You may want to create a custom DataGridViewTextBoxCell which uses the MaskedTextox control as its editing control (instead of the regular TextBox control). You would have to create a DataGridViewMaskedTextBoxCell & a DataGridViewMaskedTextBoxEditingControl class (and optionally a DataGridViewMaskedTextBoxColumn class).
If you want your custom cell to look different than a regular textbox cell when it's not edited, you'll have to custom paint it.
-Regis DataGridView Developer Microsoft this post is provided "as-is" |
| Regis Brid Monday, August 29, 2005 10:47 PM |
Hi, I have experienced identical problems using the code example in the White Paper on DGV custom columns. I notice that if you use this code in the C# IDE it works just fine. This looks like it might be a bug with the VB.net version of the DGV. I just wondered if you had made any progress?
Thanks for your time.
Regards
Steve Southport UK
|
| Steve_Ainsdale Wednesday, September 27, 2006 3:05 PM |
Unfortunately the DataGridView does not support masked input out of the box. You may want to create a custom DataGridViewTextBoxCell which uses the MaskedTextox control as its editing control (instead of the regular TextBox control). You would have to create a DataGridViewMaskedTextBoxCell & a DataGridViewMaskedTextBoxEditingControl class (and optionally a DataGridViewMaskedTextBoxColumn class).
If you want your custom cell to look different than a regular textbox cell when it's not edited, you'll have to custom paint it.
-Regis DataGridView Developer Microsoft this post is provided "as-is" |
| Regis Brid Monday, August 29, 2005 10:47 PM |
You completely ignored the fact that I am trying to use the NumericUpDown in a cell. Are you saying that the NUD control cannot be used in a cell?? It is also interesting that a "Link Column" is more important from Microsofts' point of view than a numeric input column. I would venture a guess that more developers would use a grid control for numeric input than clicking on links. I guess editing the unit cost on a line item of an order is no longer important. |
| DrMicrochip Tuesday, August 30, 2005 12:42 AM |
I agree that a numericupdown control would be very useful with the DGV. This may be a little (or a lot) hoaky, but what if you created two small Button cells to the right of your text cell and had one increment up and the other decrement the value in the textbox. You would need to have the EndEdit event make sure it's numeric, however. |
| Adam Plocher Tuesday, August 30, 2005 6:55 PM |
Hi, I have experienced identical problems using the code example in the White Paper on DGV custom columns. I notice that if you use this code in the C# IDE it works just fine. This looks like it might be a bug with the VB.net version of the DGV. I just wondered if you had made any progress?
Thanks for your time.
Regards
Steve Southport UK
|
| Steve_Ainsdale Wednesday, September 27, 2006 3:05 PM |
Add this to ur code
Protected Overloads Overrides Sub OnValueChanged(ByVal e As EventArgs) ' Notify the DataGridView that the contents of the cell ' have changed. valueIsChanged = True Me.EditingControlDataGridView.NotifyCurrentCellDirty(True) MyBase.OnValueChanged(e) End Sub |
| amostafa84 Sunday, December 21, 2008 2:36 PM |
Hi dudes. I "stole" the code posted in this page and I've adapted it to create a DataGridViewMaskedTextBox Column and Cell. There are only one restriction: you must "mask" the cell when the row is created. You cannot add a column mask, for example (I think it can be adapted to automatically add the masks but I haven't figured it out yet). Thanks very much to DrMicrochip and amostafa84 who posted the code that helped me to do this. This is the code when a user adds the row:
private void dataGridView1_UserAddedRow(Object sender, DataGridViewRowEventArgs e)
{
DataGridViewMaskedTextBoxCell dmtxt = (DataGridViewMaskedTextBoxCell)dataGridView1[0, e.Row.Index];
dmtxt.CellMask = "00.00";
}
And this is the class code:
public class DataGridViewMaskedTextBoxCell : DataGridViewTextBoxCell
{
public DataGridViewMaskedTextBoxCell()
: base()
{
}
private String Mask;
public String CellMask
{
get { return Mask; }
set {
Mask = value;
DataGridViewMaskedTextBoxEditingControl dgvmtbex = (DataGridViewMaskedTextBoxEditingControl)DataGridView.EditingControl;
if (value != null)
dgvmtbex.Mask = value;
else
dgvmtbex.Mask = String.Empty;
}
}
public override void InitializeEditingControl(Int32 rowIndex, Object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
DataGridViewMaskedTextBoxEditingControl dgvmtbex = (DataGridViewMaskedTextBoxEditingControl)DataGridView.EditingControl;
if (Mask != null)
dgvmtbex.Mask = Mask;
dgvmtbex.Text = this.Value.ToString();
}
public override Type EditType
{
get
{
return typeof(DataGridViewMaskedTextBoxEditingControl);
}
}
public override Type ValueType
{
get
{
return typeof(String);
}
}
public override object DefaultNewRowValue
{
get
{
return String.Empty;
}
}
}
public class DataGridViewMaskedTextBoxEditingControl : MaskedTextBox, IDataGridViewEditingControl
{
private DataGridView dataGridViewControl = null;
private Boolean valueIsChanged = false;
private Int32 rowIndexNum;
#region IDataGridViewEditingControl Members
public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
this.Font = dataGridViewCellStyle.Font;
}
public DataGridView EditingControlDataGridView
{
get
{
return this.dataGridViewControl;
}
set
{
this.dataGridViewControl = value;
}
}
public object EditingControlFormattedValue
{
get
{
return this.Text;
}
set
{
this.Text = value.ToString();
}
}
public int EditingControlRowIndex
{
get
{
return rowIndexNum;
}
set
{
rowIndexNum = value;
}
}
public bool EditingControlValueChanged
{
get
{
return valueIsChanged;
}
set
{
valueIsChanged = value;
}
}
public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
{
return true;
}
public Cursor EditingPanelCursor
{
get { return base.Cursor; }
}
public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
{
return this.Text;
}
public void PrepareEditingControlForEdit(bool selectAll)
{
//do nothing
}
public bool RepositionEditingControlOnValueChange
{
get { return false; }
}
protected override void OnTextChanged(EventArgs e)
{
valueIsChanged = true;
this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
base.OnTextChanged(e);
}
#endregion
}
Ing Rosell |
| fabrosell Thursday, September 24, 2009 2:55 PM |