2013-04-23 3 views
2

Итак, я получил эту проблему в WinForms, по крайней мере, я думаю, что это проблема, и я не могу понять, как ее разрешить.Проверка WinForms без подвешивания других элементов управления

В принципе, когда я реализую обработчик события Validating для элемента управления, я устанавливаю значение CancelEventArgs.Cancel в true, когда элемент управления не проверяет его. Пример кода:

private void NameTextBox_Validating(object sender, CancelEventArgs e) { 
    // Assume Cool Validation Logic. 
    // 
    // ... 
    var isValid = false; 
    if (!isValid) { 
     e.Cancel = true; 

     // Set an Error Provider Message. 
     // 
     // ... 
    } 
} 

Это вызывает повсюду весь пользовательский интерфейс. Я не могу выбрать какой-либо другой элемент управления, минимизировать окно родительской формы или событие, выходящее из окна родительской формы. Таким образом, я нашел аналогичный вопрос, ответ которого предполагает реализацию обработчика события FormClosing для родительской формы и установка FormClosingEventArgs.Cancel в false.

Проблема в том, что обработчик событий никогда не вызывается до тех пор, пока мой элемент управления недействителен. У меня такое чувство, что это может иметь какое-то отношение к моей контрольной иерархии, хотя я не уверен на 100%. Если это помогает, то это:

-- Parent Form 

---- Custom User Control 

------ Text Box Control (<-- Causes Hang) 

Любые мысли будут оценены.

ответ

5

я нашел решение, которое было так просто, я на самом деле расстроился я потратил так много часов моей жизни ударяя головой против клавиатуры.

Просто установите свойство ContainerControl.AutoValidate родительского контейнера на EnableAllowFocusChange и проблема решена. «Родительский контейнер» в этом контексте означает контейнер, в котором на самом деле находятся элементы управления вводами.

Если у вас есть иерархия управления, вы также можете установить свойство ContainerControl.AutoValidate на Inherit и просто установить самый внешний контейнер в EnableAllowFocusChange.

Надеюсь, что это поможет кому-то в будущем.

-1

Вы можете использовать асинхронные/Await или BackgroundWorker обрабатывать ваши проверки отключения потока пользовательского интерфейса:

// in your init code... 
textbox.TextChanged+=(s,e)=>Validate(); 


// and this is the Validation worker 
BackgroundWorker validateWorker = null; 
bool isValid = false; 

private void Validate(){ 
    if (validateWorker != null){ 
    validateWorker.CancelAsync(); 
    } 
    isValid = false; 
    string validateValue = textbox.Text; 

    BackgroundWorker localCopy = validateWorker = new BackgroundWorker(); 
    validateWorker.WorkerSupportsCancellation = true; 
    validateWorker.DoWork+=(s,e)=>{ 
    if (CoolValidationAssumed(validateValue) && !localCopy.CancellationPending) 
     isValid = true; 
    }; 
    validateWorker.RunWorkerCompleted += (s, e) =>{ 
    if (!localCopy.CancellationPending && !isValid) 
     textbox.Color = Colors.Red; 
    } 
    validationWorker.RunWorkerAsync(); 
} 
+0

Но не будет ли make 'ValidateChildren()' всегда возвращать true? – 9ee1

+0

@ 9ee1 вы можете проверить, что вам нравится в обратном потоке, но сначала вам нужно скопировать все данные пользовательского интерфейса в вашу модель и проверить модель (или временный экземпляр), чтобы элементы управления пользовательского интерфейса не были доступны. –

+0

I Я не уверен, что это будет работать с Data Binding. Кроме того, если вы посмотрите на источник для 'ValidateChildren()', который, кстати, будет вызван для привязки данных к потоку пользовательского интерфейса, ему абсолютно необходима реализация 'Validating' для установки' e.Cancel = true; ' , В противном случае предполагается, что ваши элементы управления действительны, и если вы используете привязку данных, это позволит выполнить операцию привязки. Спасибо, хотя за то, что нашли время, чтобы помочь, вы были единственными :) – 9ee1

Смежные вопросы