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) { // Prevent illegal characters 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) { // Prevent duplicates of decimal point and minus sign if ((e.KeyChar == '.' || e.KeyChar == '-') && CurrentText.IndexOf(e.KeyChar) >= 0) e.Handled = true; else { // Prevent too many digits on either side of decimal point 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; } // if (DecimalPos > MaxDecimalPos) // e.Handled = true; // else // if (CurrentText.Length > DecimalPos + 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; // Create the AllowedChars array for the KeyPress event handler 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'}; // Create the FormatString property value 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; // Create the first half of the FormatString property 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"; // if (this.m_Minimum < 0) // this.m_FormatString = "-" + this.m_FormatString; // Finally, create the formatting 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;} } // [Description("The string to use with ToString to format.")] // [DefaultValue("##0")] // public string FormatString // { // get {return this.m_FormatString;} // set {this.m_FormatString = value;} // } #endregion }~~Bonnie