Поскольку MaskedTextBox
не вариант, и вы предпочитаете TextBox
, то, возможно, это приведет к чему-то.
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
}
}
Шаги и описание
Извлечь новый класс из TextBox
control.
Переопределить метод OnKeyPress
, чтобы разрешить управление, Только клавиши di git и . .
Переопределите метод OnTextChanged
, чтобы проверить измененный текст с помощью функции IsValidInput
и удалить последний введенный символ, если функция возвращает false
.
Функция IsValidInput
проверяет, может ли введенный текст создать действительный IP-адрес или его часть.
Делегат IsValidIP4Part
получает части IP из функции IsValidInput
и проверяет, являются ли они действительными частями IP4.
IsValidIP
только для чтения свойство возвращает, является ли текст действительным IP-адресом. Как вы знаете, IPAddress.TryParse(..)
также вернет true
, если вы передадите, например, 1
или 192.168
, потому что он анализирует их как 0.0.0.1
и 192.0.0.168
соответственно. Так что здесь это не поможет.
Настраиваемое событие InvalidInput
возникает при каждом нажатии недопустимой клавиши и если Text
не образует действительный IP-адрес или часть этого Таким образом, событие может быть обработано в реализации, чтобы при необходимости предупредить пользователя.
Вот и все.
Редактировать: недопустимое выражение выражение 'int' Исправить ошибку
Заменить:
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));
}
На:
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));
}
Связано
▶ Как вводить текстовые поля в произвольном формате?