问题
I have a textbox C# for IP addressing; validating IP address. However, I'm trying to limit to numbers and the amount of dots a user can enter in for the IP address. This way it limits errors.
Seems I'm able to enter one dot, I would like to increase that number to three. I can create a "Regex.IsMatch" and validate using "IPAddress", but I'm just trying to limit what the user can enter before pressing a button to proceed.
Is there a way to do this? Searching the Internet haven't found any way to do this.
string pattern = @"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b";
bool CKDots = Regex.IsMatch(TracertIP, pattern);
private void txtTracerouteIP_KeyPress(object sender, KeyPressEventArgs e)
{
// Enter only numbers.
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '.'))
{
e.Handled = true;
}
// Only one dot, but I need three.
//if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
//{
// e.Handled = true;
//}
}
回答1:
Since the MaskedTextBox
is not an option and you prefer the TextBox
, then maybe this would lead to something.
using System;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;
namespace YourNamespace
{
[DesignerCategory("Code")]
class IPTextBox : TextBox
{
#region Constructors
public IPTextBox() : base() { }
#endregion
#region Public Properties
[Browsable(false)]
public bool IsValidIP { get { return IsValidInput(true); } }
#endregion
#region Private Methods
private readonly Func<string, bool> IsValidIP4Part = x =>
{ return x.Length > 1 && x.StartsWith("0") ? false
: int.TryParse(x, out int y) && y < 256; };
private bool IsValidInput(bool full = false)
{
var split = Text.Split('.');
var parts = split.Where(x => int.TryParse(x, out int y));
return !Text.StartsWith(".") &&
!Text.EndsWith("..") &&
split.Length < 5 &&
parts.All(x => IsValidIP4Part(x));
}
#endregion
#region Base
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
if (!IsValidInput())
{
SendKeys.SendWait("{BS}");
OnInvalidInput();
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
if (!char.IsControl(e.KeyChar) &&
!char.IsDigit(e.KeyChar) &&
e.KeyChar != '.')
{
e.Handled = true;
OnInvalidInput();
}
}
#endregion
#region Custom Events
public event EventHandler InvalidInput;
protected virtual void OnInvalidInput()
{
var h = InvalidInput;
h?.Invoke(this, EventArgs.Empty);
}
#endregion
}
}
Steps & Description
Derive a new class from
TextBox
control.Override the
OnKeyPress
method to permit the control, digit, and . keys only.Override the
OnTextChanged
method to validate the modified text thru theIsValidInput
function and delete the last entered character if the function returnsfalse
.The
IsValidInput
function checks whether the entered text can produce a valid IP address or a part of it.The
IsValidIP4Part
delegate receives the IP parts from theIsValidInput
function and checks whether they are valid IP4 parts or not.The
IsValidIP
read-only property returns whether the text is a valid IP address. As you know, theIPAddress.TryParse(..)
will also returntrue
if you pass for example1
or192.168
because it parses them as0.0.0.1
and192.0.0.168
respectively. So it won't help here.The custom event
InvalidInput
is raised whenever an invalid key is pressed and if theText
does not form a valid IP address or a part of it. So, the event can be handled in the implementation to alert the user if necessary.
That's it all.
Edit: Invalid expression term 'int' Issue fix
Replace:
private readonly Func<string, bool> IsValidIP4Part = x =>
{
return x.Length > 1 && x.StartsWith("0") ? false
: int.TryParse(x, out int y) && y < 256;
};
private bool IsValidInput(bool full = false)
{
var split = Text.Split('.');
var parts = split.Where(x => int.TryParse(x, out int y));
return !Text.StartsWith(".") &&
!Text.EndsWith("..") &&
split.Length < 5 &&
parts.All(x => IsValidIP4Part(x));
}
With:
private bool IsValidIP4Part(string input)
{
int y;
return input.Length > 1 && input.StartsWith("0") ? false
: int.TryParse(input, out y) && y < 256;
}
private bool IsValidInput(bool full = false)
{
int y;
var split = Text.Split('.');
var parts = split.Where(x => int.TryParse(x, out y));
return !Text.StartsWith(".") &&
!Text.EndsWith("..") &&
split.Length < 5 &&
parts.All(x => IsValidIP4Part(x));
}
Related
▶ How to TextBox inputs of custom format?
回答2:
We can keep it simple and use the validating event:
this.txtTracerouteIP.Validating += this.txtTracerouteIP_Validating;
And then:
string pattern = @"^\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b$";
private void txtTracerouteIP_Validating(object sender, CancelEventArgs e)
{
if (!Regex.IsMatch(txtTracerouteIP.Text, pattern))
{
MessageBox.Show("IP Address must be in the format '255.255.255.255'!");
txtTracerouteIP.SelectAll();
e.Cancel = true;
}
}
来源:https://stackoverflow.com/questions/60765586/three-dots-in-textbox