>It would be good to see the code in C#.Okey dokey .... here ya go.
This example has been subclassed from MyTextBox subclass and will need additional tweaking if you want to sub-class from the System.Windows.Forms.TextBox. In particular notice that all the eventhandlers are overridden from the parent class. But other than that minor tweaking, this should work just fine.
public class MyNumericTextBox : MyTextBox
{
#region Declarations
private int m_DecimalPlaces = 0;
private decimal m_Maximum = 100;
private decimal m_Minimum = 0;
protected char[] AllowedChars = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-'};
protected string m_FormatString = "##0";
private bool m_DisplayDefaultZero = true;
#endregion
#region Constructor
public MyNumericTextBox()
{
this.MaxLength = 3;
this.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
}
#endregion
#region Methods
public void SetText(object val)
{
if (this.m_Minimum > 0)
{
if (val is Decimal)
this.Text = ((decimal)val).ToString(this.m_FormatString);
}
else
{
if (val is int)
this.Text = ((int)val).ToString(this.m_FormatString);
}
}
#endregion
#region Events
protected override void FormatHandler(object sender, ConvertEventArgs e)
{
if(this.DisplayDefaultZero)
{
if (e.Value == System.DBNull.Value)
e.Value = (int)0;
}
if (e.Value is Decimal && e.DesiredType == typeof(string))
e.Value = ((decimal)e.Value).ToString(this.m_FormatString);
else if (e.Value is int && e.DesiredType == typeof(string))
e.Value = ((int)e.Value).ToString(this.m_FormatString);
}
protected override void ParseHandler(object sender, ConvertEventArgs e)
{
if (((string)e.Value).Trim().Length == 0)
e.Value = "0";
if (e.DesiredType == typeof(decimal))
e.Value = Decimal.Parse((string)e.Value, System.Globalization.NumberStyles.Any);
else if (e.DesiredType == typeof(int))
{
string[] s = ((string)e.Value).Trim().Split('.');
e.Value = Decimal.Parse(s[0], System.Globalization.NumberStyles.Any);
}
}
protected override void KeyPressHandler(object sender, KeyPressEventArgs e)
{
bool allowed = false;
for (int i = 0; i < this.AllowedChars.Length; i++)
{
if (e.KeyChar == this.AllowedChars[i])
{
allowed = true;
break;
}
}
if (allowed == true)
{
string CurrentText = this.Text;
if (this.SelectionLength > 0)
{
int i = this.Text.IndexOf(this.SelectedText);
int j = i + this.SelectionLength;
if (i > 0 && j == this.TextLength)
CurrentText = this.Text.Substring(0, i);
else
if (i > 0)
CurrentText = this.Text.Substring(0, i) + this.Text.Substring(j);
else
CurrentText = this.Text.Substring(j);
}
if (CurrentText != this.SelectedText)
{
if ((e.KeyChar == '.' || e.KeyChar == '-') &&
CurrentText.IndexOf(e.KeyChar) >= 0)
e.Handled = true;
else
{
if (this.m_DecimalPlaces > 0 &&
e.KeyChar != '.' && e.KeyChar != '-' && e.KeyChar != (char)Keys.Back)
{
int MaxDecimalPos = this.MaxLength - this.m_DecimalPlaces - 1;
int DecimalPos = CurrentText.IndexOf('.');
int DecimalDigits = CurrentText.Length - DecimalPos - 1;
if (DecimalPos < 0)
{
if (CurrentText.Length >= MaxDecimalPos)
e.Handled = true;
}
else
if (this.SelectionStart <= DecimalPos)
{
if (DecimalPos == MaxDecimalPos)
e.Handled = true;
}
else
if (this.SelectionStart >= CurrentText.Length)
{
if (DecimalDigits == this.m_DecimalPlaces)
e.Handled = true;
}
}
}
}
}
else
e.Handled = true;
}
protected override void ValidatingHandler(object sender, CancelEventArgs e)
{
if (this.Text.Trim().Length == 0)
return;
try
{
decimal test = Decimal.Parse(this.Text);
if (test > this.m_Maximum || test < this.m_Minimum)
{
string message = "The value for this field must be between " +
this.m_Maximum.ToString() + " and " + this.m_Minimum.ToString() + "!";
string caption = "Value out of range";
MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
e.Cancel = true;
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
#endregion
#region Properties
[Description("The number of digits to display after the decimal.")]
[DefaultValue(0)]
public int DecimalPlaces
{
get {return this.m_DecimalPlaces;}
set
{
this.m_DecimalPlaces = value;
if (value > 0 && this.m_Minimum < 0)
this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
else if (value > 0)
this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
else if (this.m_Minimum < 0)
this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
else
this.AllowedChars = new char[] {(char)Keys.Back, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'};
string[] format = this.m_FormatString.Split(new char[] {'.'}, 2);
if (value > 0)
{
string s = new string('0', value);
this.m_FormatString = format[0] + "." + s;
}
else
this.m_FormatString = format[0];
this.MaxLength = this.m_FormatString.Length;
if (this.m_Minimum < 0 && this.m_Minimum.ToString().Length > this.m_Maximum.ToString().Length)
this.MaxLength++;
}
}
[Description("The maximum value allowed in the field.")]
[DefaultValue(100)]
public decimal Maximum
{
get {return this.m_Maximum;}
set
{
if (value < this.m_Minimum)
return;
this.m_Maximum = value;
this.MaxLength = value.ToString().Length;
int max = this.m_Minimum.ToString().Length;
if (this.m_Minimum < 0 && max > this.MaxLength)
this.MaxLength = max;
if (this.MaxLength > 2 && value.ToString().Length < this.m_Minimum.ToString().Length)
this.m_FormatString = new string('#', this.MaxLength - 2) + "0";
else if (this.MaxLength > 1)
this.m_FormatString = new string('#', this.MaxLength - 1) + "0";
else
this.m_FormatString = "0";
this.DecimalPlaces = this.m_DecimalPlaces;
}
}
[Description("The minimum value allowed in the field.")]
[DefaultValue(0)]
public decimal Minimum
{
get {return this.m_Minimum;}
set
{
if (value > this.m_Maximum)
return;
this.m_Minimum = value;
this.Maximum = this.m_Maximum;
}
}
[Description("Enable if you don't want to display a zero in this field")]
public bool DisplayDefaultZero
{
get {return this.m_DisplayDefaultZero;}
set {this.m_DisplayDefaultZero = value;}
}
#endregion
}
~~Bonnie