2010-12-16 3 views
6

폼에 여러 개의 입력 컨트롤이있는 WinForm 응용 프로그램이 있습니다. 유효성 검사 이벤트 처리기 (Validating 또는 Validated)에서 유효성이 검사 된 값을 기준으로 다음에 활성화 할 컨트롤을 결정해야합니다..NET에서 유효성 검사 후 컨트롤에 포커스를 설정하는 방법

Validating 이벤트의 마이크로 소프트의 문서에서는 상태 :

주의

입력,의 GotFocus가,두고 LostFocus, 검증 내에서 포커스를 설정하려고, 또는 검증 된 이벤트 핸들러하지 마십시오. 그렇게하면 응용 프로그램이나 운영 체제가 응답을 중지 할 수 있습니다. 자세한 내용은 "키보드 입력 참조"절의 WM_KILLFOCUS 항목과 MSDN 라이브러리의 "메시지 및 메시지 큐 정보"항목의 "메시지 교착 상태"절 (http : // msdn.microsoft.com/library)을 참조하십시오. .

활성 상태가 될 컨트롤을 설정하고 제한이 언급되지 않은 Form 클래스의 속성은 ActiveControl입니다. 몇 시간 동안 웹 검색을 한 후에도 다른 해결책을 찾지 못했습니다.

Validate 이벤트 처리기에서 Focus 대신 ActiveControl 속성을 설정하면 원하는 컨트롤을 적극적으로 활성화 할 수있는 안전한 방법입니까? 그렇지 않다면 해결책이 있습니까?

.NET Compact Framework에는 ActiveControl 속성이 없으므로 누구나 솔루션을 제안 할 수 있습니까?

답변

9

예, 검증 이벤트 기간 동안 초점을 변경하는 것은 매우 곤란하다. 이벤트는 포커스가 변경되는 정확한 시간에 발생합니다. 다음 컨트롤은 Windows와 관련하여 이미 포커스를 얻었지만 논리적 폼 상태는 컨트롤의 유효성을 확인하는 데 여전히 초점을두고 있습니다. e.Cancel을 true로 설정하면 Winforms는 Windows 포커스 상태를 실행 취소해야합니다. 그렇지 않으면 이벤트 이후에 논리 상태를 업데이트해야합니다. 너 자신에게 초점을 바꿀 때 잘못 될 수있는 다양한 것들이있다.

포커스가 분류 될 때까지 기다리는 것이 중요합니다. 가장 좋은 방법은 모든 작업이 완료되고 양식이 다시 유휴 상태가 될 때까지 코드를 지연시키는 것입니다. Control.BeginInvoke() 메서드를 사용하여 완전히 정리할 수 있습니다. 이런 식으로 뭔가 :

private delegate void ChangeFocusDelegate(Control ctl); 

    private void textBox1_Validating(object sender, CancelEventArgs e) { 
     int value; 
     if (!int.TryParse(textBox1.Text, out value)) e.Cancel = true; 
     else { 
      if (value == 1) this.BeginInvoke(new ChangeFocusDelegate(changeFocus), textBox2); 
      else this.BeginInvoke(new ChangeFocusDelegate(changeFocus), textBox3); 
     } 
    } 
    private void changeFocus(Control ctl) { 
     ctl.Focus(); 
    } 
+0

와우, 영리한 대답! Delegate.BeginInvoke()와 Control.BeginInvoke() 사이의 차이점을 알기 전에는 위임 된 메서드가 EndInvoke()를 호출해야한다고 생각했습니다. \t [.net - Invoke()와 BeginInvoke의 차이점] [1] [1] http://stackoverflow.com/questions/229554/whats-the-difference-between-invoke-and-begininvoke – Suncat2000

1

Validating 이벤트 처리기로 전달되는 CancelEventArgsCancel property을 False로 설정해 보았습니까?

현재 컨트롤에 포커스를두고 유효성 검사가 실패 할 경우 다음 컨트롤이 포커스를받지 못하도록하는 의도 된 방법입니다. 예를 들면 :

private void TextBox1_Validating(object sender, System.ComponentModel.CancelEventArgs e) 
{ 
    //Make sure that the textbox is not left blank 
    if (string.IsNullOrEmpty(TextBox1.Text)) 
    { 
     e.Cancel = true; 
    } 
} 
+0

감사합니다. 나는 이것에 대해 안다. 그러나 초점을 바꾸는 것만을 유지한다. 특정 컨트롤에 포커스를 설정할 수 없습니다. – Suncat2000

+0

@Suncat : 예, 당신이 다른 컨트롤에 초점을 맞추고 싶다는 질문에서 말할 수 없었습니다. 한스는 이미 당신에게 어떻게해야하는지에 대한 좋은 대답을주었습니다. –

0

이 스레드는 오래,하지만 난 생각의 몇 가지 있습니다

  1. 모든 컨트롤이 태그의 속성이 있습니다.원하는 컨트롤에 고유 한 태그 값에 포커스를 둔 다음 해당 컨트롤을 찾기 위해 컨트롤을 반복하는 메서드를 만드는 방법은 무엇입니까? 그런 다음 초점을 설정할 수 있습니다.

  2. Validating 이벤트를 사용하는 대신 Leaving을 사용하지 않는 이유는 무엇입니까? 같은 단점이있는 것 같지 않습니다.

관련 문제