यहाँ एक साधारण स्टैंडअलोन Winforms कस्टम नियंत्रण है, जो मानक TextBox से लिया गया है, जो केवल System.Int32 इनपुट की अनुमति देता है (इसे अन्य प्रकार जैसे System.Int64, आदि के लिए आसानी से अनुकूलित किया जा सकता है)। यह कॉपी / पेस्ट संचालन और नकारात्मक संख्याओं का समर्थन करता है:
public class Int32TextBox : TextBox
{
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
NumberFormatInfo fi = CultureInfo.CurrentCulture.NumberFormat;
string c = e.KeyChar.ToString();
if (char.IsDigit(c, 0))
return;
if ((SelectionStart == 0) && (c.Equals(fi.NegativeSign)))
return;
// copy/paste
if ((((int)e.KeyChar == 22) || ((int)e.KeyChar == 3))
&& ((ModifierKeys & Keys.Control) == Keys.Control))
return;
if (e.KeyChar == '\b')
return;
e.Handled = true;
}
protected override void WndProc(ref System.Windows.Forms.Message m)
{
const int WM_PASTE = 0x0302;
if (m.Msg == WM_PASTE)
{
string text = Clipboard.GetText();
if (string.IsNullOrEmpty(text))
return;
if ((text.IndexOf('+') >= 0) && (SelectionStart != 0))
return;
int i;
if (!int.TryParse(text, out i)) // change this for other integer types
return;
if ((i < 0) && (SelectionStart != 0))
return;
}
base.WndProc(ref m);
}
अद्यतन २०१ answer: मेरे पहले उत्तर में कुछ समस्याएं हैं:
- आप कुछ ऐसा टाइप कर सकते हैं जो किसी दिए गए प्रकार के पूर्णांक से अधिक है (उदाहरण के लिए 2147483648 Int32.MaxValue से अधिक है);
- अधिक आम तौर पर, टाइप किए गए परिणाम का कोई वास्तविक सत्यापन नहीं है ;
- यह केवल int32 को संभालता है, आपको प्रत्येक प्रकार (Int64, आदि) के लिए विशिष्ट टेक्स्टबॉक्स व्युत्पन्न नियंत्रण लिखना होगा।
इसलिए मैं एक और संस्करण के साथ आया, जो अधिक सामान्य है, जो अभी भी कॉपी / पेस्ट, + और - साइन, आदि का समर्थन करता है।
public class ValidatingTextBox : TextBox
{
private string _validText;
private int _selectionStart;
private int _selectionEnd;
private bool _dontProcessMessages;
public event EventHandler<TextValidatingEventArgs> TextValidating;
protected virtual void OnTextValidating(object sender, TextValidatingEventArgs e) => TextValidating?.Invoke(sender, e);
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (_dontProcessMessages)
return;
const int WM_KEYDOWN = 0x100;
const int WM_ENTERIDLE = 0x121;
const int VK_DELETE = 0x2e;
bool delete = m.Msg == WM_KEYDOWN && (int)m.WParam == VK_DELETE;
if ((m.Msg == WM_KEYDOWN && !delete) || m.Msg == WM_ENTERIDLE)
{
DontProcessMessage(() =>
{
_validText = Text;
_selectionStart = SelectionStart;
_selectionEnd = SelectionLength;
});
}
const int WM_CHAR = 0x102;
const int WM_PASTE = 0x302;
if (m.Msg == WM_CHAR || m.Msg == WM_PASTE || delete)
{
string newText = null;
DontProcessMessage(() =>
{
newText = Text;
});
var e = new TextValidatingEventArgs(newText);
OnTextValidating(this, e);
if (e.Cancel)
{
DontProcessMessage(() =>
{
Text = _validText;
SelectionStart = _selectionStart;
SelectionLength = _selectionEnd;
});
}
}
}
private void DontProcessMessage(Action action)
{
_dontProcessMessages = true;
try
{
action();
}
finally
{
_dontProcessMessages = false;
}
}
}
public class TextValidatingEventArgs : CancelEventArgs
{
public TextValidatingEventArgs(string newText) => NewText = newText;
public string NewText { get; }
}
Int32 के लिए, आप इसे इस तरह से प्राप्त कर सकते हैं:
public class Int32TextBox : ValidatingTextBox
{
protected override void OnTextValidating(object sender, TextValidatingEventArgs e)
{
e.Cancel = !int.TryParse(e.NewText, out int i);
}
}
या w / o व्युत्पत्ति, इस तरह से नई TextValidating घटना का उपयोग करें:
var vtb = new ValidatingTextBox();
...
vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);
लेकिन जो अच्छा है वह किसी भी स्ट्रिंग, और किसी भी सत्यापन रूटीन के साथ काम करता है।