159 lines
4.4 KiB
C#
159 lines
4.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace JRCookbookControls
|
|
{
|
|
[System.Serializable()]
|
|
public class JRCookbookNumericTextBox: TextBox
|
|
{
|
|
private String _strLastValue = String.Empty;
|
|
private bool _blnAllowNegative = true;
|
|
private bool _blnAllowDecimal = true;
|
|
private bool _blnAllowEmpty = true;
|
|
|
|
public JRCookbookNumericTextBox()
|
|
{
|
|
this.TextChanged += new System.EventHandler(this.NumericTextBox_TextChanged);
|
|
this.Validating += new System.ComponentModel.CancelEventHandler(this.NumericTextBox_Validating);
|
|
}
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
|
public bool AllowDecimal
|
|
{
|
|
get
|
|
{
|
|
return _blnAllowDecimal;
|
|
}
|
|
set
|
|
{
|
|
_blnAllowDecimal = value;
|
|
}
|
|
|
|
}
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
|
public bool AllowNegative
|
|
{
|
|
get
|
|
{
|
|
return _blnAllowNegative;
|
|
}
|
|
set
|
|
{
|
|
_blnAllowNegative = value;
|
|
}
|
|
|
|
}
|
|
|
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
|
|
public bool AllowEmpty
|
|
{
|
|
get
|
|
{
|
|
return _blnAllowEmpty;
|
|
}
|
|
set
|
|
{
|
|
_blnAllowEmpty = value;
|
|
}
|
|
|
|
}
|
|
|
|
private void NumericTextBox_TextChanged(System.Object sender, System.EventArgs e)
|
|
{
|
|
bool blnValueIsOK = true;
|
|
Int32 intPosition = 0;
|
|
bool blnAlreadySeenDecimal = false;
|
|
|
|
//Allow digits, one decimal point, and minus sign (if first character only)
|
|
foreach (char chrCharacter in this.Text)
|
|
{
|
|
switch (chrCharacter)
|
|
{
|
|
case char x when (x >= '0' && x <= '9'):
|
|
//OK
|
|
break;
|
|
case '-':
|
|
if (intPosition > 0 || AllowNegative == false)
|
|
{
|
|
blnValueIsOK = false;
|
|
}
|
|
break;
|
|
case '.':
|
|
if (blnAlreadySeenDecimal)
|
|
{
|
|
blnValueIsOK = false;
|
|
}
|
|
else
|
|
{
|
|
blnAlreadySeenDecimal = true;
|
|
}
|
|
break;
|
|
default:
|
|
blnValueIsOK = false;
|
|
break;
|
|
}
|
|
|
|
intPosition += 1;
|
|
|
|
if (!blnValueIsOK)
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if (blnValueIsOK)
|
|
{
|
|
_strLastValue = this.Text;
|
|
}
|
|
else
|
|
{
|
|
Int32 oldSelectionStart = this.SelectionStart - 1;
|
|
this.Text = _strLastValue;
|
|
if (oldSelectionStart >= 0 && oldSelectionStart <= this.Text.Length)
|
|
{
|
|
this.SelectionStart = oldSelectionStart;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private void NumericTextBox_Validating(System.Object sender, System.ComponentModel.CancelEventArgs e)
|
|
{
|
|
if (this.Text == String.Empty)
|
|
{
|
|
if (AllowEmpty)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
e.Cancel = true;
|
|
}
|
|
}
|
|
|
|
//Now that we know it's not empty, make sure we have a digit
|
|
foreach (char chrCharacter in this.Text)
|
|
{
|
|
switch (chrCharacter)
|
|
{
|
|
case char x when (x >= '0' && x <= '9'):
|
|
//OK
|
|
return;
|
|
}
|
|
}
|
|
|
|
//If we got here, we have hyphen or period, but no digits
|
|
e.Cancel = true;
|
|
}
|
|
|
|
}
|
|
|
|
}
|