📄 numericupdown.cs
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Diagnostics;
namespace MobileControls
{
public partial class NumericUpDown : UserControl, INotifyPropertyChanged
{
enum NumericUpDownProperties
{
DecimalPlaces,
Minimum,
Maximum,
Value
}
public NumericUpDown()
{
InitializeComponent();
}
private int _decimalPlaces = 0;
private decimal _min = 0;
private decimal _max = 100;
private decimal _value = 0;
private bool _enforceMinMax = true;
public int DecimalPlaces
{
get { return _decimalPlaces; }
set
{
if (_decimalPlaces < 0)
{
return;
// throw new ArgumentException("'DecimalPlaces' cannot be negative.");
}
bool changed = (_decimalPlaces != value);
_decimalPlaces = value;
if (changed)
OnPropertyChanged(NumericUpDownProperties.DecimalPlaces);
}
}
public decimal Minimum
{
get { return _min; }
set
{
bool changed = (_min != value);
_min = value;
if (changed)
OnPropertyChanged(NumericUpDownProperties.Minimum);
}
}
public decimal Maximum
{
get { return _max; }
set
{
bool changed = (_max != value);
_max = value;
if (changed)
OnPropertyChanged(NumericUpDownProperties.Maximum);
}
}
public decimal Value
{
get { return _value; }
set
{
decimal correctedValue = value;
bool refreshNeeded = (_value != value);
if (_enforceMinMax)
{
//if entered value exceeds min or max, quietly reset
if (value > _max)
{
correctedValue = _max;
}
else if (value < _min)
{
correctedValue = _min;
}
}
_value = correctedValue;
if (refreshNeeded)
OnPropertyChanged(NumericUpDownProperties.Value);
}
}
public bool EnforceMinMax
{
get { return _enforceMinMax; }
set { _enforceMinMax = value; }
}
private decimal GetFactor()
{
int order = 0;
string strValue = txt.Text;
if (!string.IsNullOrEmpty(strValue)
&& (txt.SelectionStart > -1)
/*&& (txt.SelectionLength > 0)*/)
{
int decimalIndex = strValue.IndexOf('.');
if (decimalIndex == -1)
decimalIndex = strValue.Length;
if (decimalIndex > txt.SelectionStart)
order = (decimalIndex - txt.SelectionStart) - 1;
else
{
order = (decimalIndex - txt.SelectionStart);
//should not be lower than the # of decimal places
if ((-1 * order) > _decimalPlaces)
order = (-1 * _decimalPlaces);
}
}
return (decimal)Math.Pow(10.0, (double)order);
}
private void PerformUp()
{
Value += GetFactor();
}
private void PerformDown()
{
Value -= GetFactor();
}
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(NumericUpDownProperties property)
{
switch (property)
{
case NumericUpDownProperties.DecimalPlaces:
//update the rest of the properties
//OnPropertyChanged(NumericUpDownProperties.Minimum);
//OnPropertyChanged(NumericUpDownProperties.Maximum);
OnPropertyChanged(NumericUpDownProperties.Value);
break;
//case NumericUpDownProperties.Minimum:
// num.Minimum = _min * GetFactor();
// break;
//case NumericUpDownProperties.Maximum:
// num.Maximum = _max * GetFactor();
// break;
case NumericUpDownProperties.Value:
int selectedIndex = txt.SelectionStart;
string formatString = "{0:F" + _decimalPlaces + "}";
txt.Text = String.Format(formatString, _value);
txt.SelectionStart = selectedIndex;
if (_enforceMinMax)
{
btnUp.Enabled = (_value < _max);
btnDown.Enabled = (_value > _min);
}
break;
}
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property.ToString()));
}
private void txt_Validating(object sender, CancelEventArgs e)
{
decimal? value = null;
try
{
value = decimal.Parse(txt.Text);
}
catch (Exception)
{ }
if (value.HasValue)
{
Value = value.Value;
}
else
{
//overright value
OnPropertyChanged(NumericUpDownProperties.Value);
}
}
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
NumberFormatInfo numberFormatInfo = CultureInfo.CurrentCulture.NumberFormat;
string decimalSeparator = numberFormatInfo.NumberDecimalSeparator;
string groupSeparator = numberFormatInfo.NumberGroupSeparator;
string negativeSign = numberFormatInfo.NegativeSign;
string keyInput = e.KeyChar.ToString();
if (Char.IsDigit(e.KeyChar))
{
// Digits are OK
}
else if (keyInput.Equals(decimalSeparator) || keyInput.Equals(groupSeparator) ||
keyInput.Equals(negativeSign))
{
// Decimal separator is OK
}
else if (e.KeyChar == '\b')
{
// Backspace key is OK
}
else
{
// Consume this invalid key and beep
e.Handled = true;
}
}
private void txt_TextChanged(object sender, EventArgs e)
{
}
private void btnUp_Click(object sender, EventArgs e)
{
PerformUp();
}
private void btnDown_Click(object sender, EventArgs e)
{
PerformDown();
}
private void txt_KeyDown(object sender, KeyEventArgs e)
{
if ((int)e.KeyCode == (int)Keys.Down)
{
PerformDown();
e.Handled = true;
}
else if ((int)e.KeyCode == (int)Keys.Up)
{
PerformUp();
e.Handled = true;
}
}
private void txt_GotFocus(object sender, EventArgs e)
{
OnGotFocus(EventArgs.Empty);
}
private void txt_LostFocus(object sender, EventArgs e)
{
OnLostFocus(EventArgs.Empty);
}
private void btnUp_GotFocus(object sender, EventArgs e)
{
OnGotFocus(EventArgs.Empty);
}
private void btnUp_LostFocus(object sender, EventArgs e)
{
OnLostFocus(EventArgs.Empty);
}
private void btnDown_GotFocus(object sender, EventArgs e)
{
OnGotFocus(EventArgs.Empty);
}
private void btnDown_LostFocus(object sender, EventArgs e)
{
OnLostFocus(EventArgs.Empty);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -