Я понимаю, что эта ветка довольно старая, но я решил опубликовать решение, которое придумал.
Самая большая проблема с проверкой на WinForms заключается в том, что проверка выполняется только тогда, когда элемент управления «потерял фокус». Таким образом, пользователь должен щелкнуть внутри текстового поля, а затем щелкнуть где-нибудь еще, чтобы выполнить процедуру проверки. Это нормально, если вас беспокоит только правильность введенных данных. Но это не работает, если вы пытаетесь убедиться, что пользователь не оставил текстовое поле пустым, пропустив его.
В моем решении, когда пользователь нажимает кнопку отправки для формы, я проверяю каждый элемент управления в форме (или любой другой указанный контейнер) и использую отражение, чтобы определить, определен ли метод проверки для элемента управления. Если это так, метод проверки выполняется. Если какая-либо из проверок завершается неудачно, процедура возвращает ошибку и позволяет остановить процесс. Это решение хорошо работает, особенно если у вас есть несколько форм для проверки.
1) Просто скопируйте и вставьте этот фрагмент кода в ваш проект. Мы используем Reflection, поэтому вам нужно добавить System.Reflection в ваши операторы использования
class Validation
{
public static bool hasValidationErrors(System.Windows.Forms.Control.ControlCollection controls)
{
bool hasError = false;
// Now we need to loop through the controls and deterime if any of them have errors
foreach (Control control in controls)
{
// check the control and see what it returns
bool validControl = IsValid(control);
// If it's not valid then set the flag and keep going. We want to get through all
// the validators so they will display on the screen if errorProviders were used.
if (!validControl)
hasError = true;
// If its a container control then it may have children that need to be checked
if (control.HasChildren)
{
if (hasValidationErrors(control.Controls))
hasError = true;
}
}
return hasError;
}
// Here, let's determine if the control has a validating method attached to it
// and if it does, let's execute it and return the result
private static bool IsValid(object eventSource)
{
string name = "EventValidating";
Type targetType = eventSource.GetType();
do
{
FieldInfo[] fields = targetType.GetFields(
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic);
foreach (FieldInfo field in fields)
{
if (field.Name == name)
{
EventHandlerList eventHandlers = ((EventHandlerList)(eventSource.GetType().GetProperty("Events",
(BindingFlags.FlattenHierarchy |
(BindingFlags.NonPublic | BindingFlags.Instance))).GetValue(eventSource, null)));
Delegate d = eventHandlers[field.GetValue(eventSource)];
if ((!(d == null)))
{
Delegate[] subscribers = d.GetInvocationList();
// ok we found the validation event, let's get the event method and call it
foreach (Delegate d1 in subscribers)
{
// create the parameters
object sender = eventSource;
CancelEventArgs eventArgs = new CancelEventArgs();
eventArgs.Cancel = false;
object[] parameters = new object[2];
parameters[0] = sender;
parameters[1] = eventArgs;
// call the method
d1.DynamicInvoke(parameters);
// if the validation failed we need to return that failure
if (eventArgs.Cancel)
return false;
else
return true;
}
}
}
}
targetType = targetType.BaseType;
} while (targetType != null);
return true;
}
}
2) Используйте стандартное событие Validating для любого элемента управления, который вы хотите проверить. Обязательно используйте e.Cancel при сбое проверки!
private void txtLastName_Validating(object sender, CancelEventArgs e)
{
if (txtLastName.Text.Trim() == String.Empty)
{
errorProvider1.SetError(txtLastName, "Last Name is Required");
e.Cancel = true;
}
else
errorProvider1.SetError(txtLastName, "");
}
3) Не пропустите этот шаг! Установите для свойства AutoValidate в форме значение EnableAllowFocusChange . Это позволит перейти на другой элемент управления, даже если проверка не пройдена.
4) Наконец, в вашем методе Submit Button вызовите метод Validation и укажите, какой контейнер вы хотите проверить. Это может быть вся форма или просто контейнер в форме, такой как Panel или Группа.
private void btnSubmit_Click(object sender, EventArgs e)
{
// the controls collection can be the whole form or just a panel or group
if (Validation.hasValidationErrors(frmMain.Controls))
return;
// if we get here the validation passed
this.close();
}
Счастливого кодирования!