এখানে একটি সাধারণ স্ট্যান্ডলোন উইনফর্মস কাস্টম নিয়ন্ত্রণ রয়েছে, এটি স্ট্যান্ডার্ড টেক্সটবক্স থেকে প্রাপ্ত, যা কেবলমাত্র 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);
}
আপডেট 2017 : আমার প্রথম উত্তরে কিছু সমস্যা রয়েছে:
- আপনি প্রদত্ত প্রকারের পূর্ণসংখ্যার চেয়ে লম্বা এমন কিছু টাইপ করতে পারেন (উদাহরণস্বরূপ 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; }
}
ইন্ট 32 এর জন্য আপনি এটি থেকে এটি পেতে পারেন:
public class Int32TextBox : ValidatingTextBox
{
protected override void OnTextValidating(object sender, TextValidatingEventArgs e)
{
e.Cancel = !int.TryParse(e.NewText, out int i);
}
}
বা ডাব্লু / ও ডেরিভেশন, নতুন টেক্সটভালিডিং ইভেন্টটি ব্যবহার করুন:
var vtb = new ValidatingTextBox();
...
vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);
তবে কি সুন্দর এটি কোনও স্ট্রিং এবং যে কোনও বৈধতা রুটিনের সাথে কাজ করে।