2010-04-07 7 views
4

내 비즈니스 개체가 구현하는 IDataErrorInfo 데이터 유효성 검사를 사용하는 WPF 응용 프로그램을 만들고 있습니다. 나는 this demo from a blog post와 협력하여 ValidatesOnDataErrors을 이해합니다.IDataErrorInfo : 페이지 제출시 유효성 검사

데모는 두 개의 텍스트 상자를 Contact 개체에 바인딩하고 데이터 바인딩에 ValidatesOnDataErrors=True을 사용하여 IDataErrorInfo 유효성 검사를 구현하는 간단한 응용 프로그램입니다. 유효하려면 텍스트 상자에 5 자 이상이 있어야합니다.

여기 내 문제가 있습니다. 데모에서는 텍스트 상자에 포커스가 없을 때마다 유효성 검사가 트리거됩니다. 사실, 텍스트 상자는 응용 프로그램이 시작될 때 잘못된 상태 (빨간색 테두리)로 초기화됩니다. 내 응용 프로그램은 사용자가 확인 버튼을 클릭하여 페이지를 제출할 때까지 유효성 검사를 연기해야합니다. 이 때 텍스트 상자의 유효성을 검사하고 유효하지 않은 경우 오류 상태로 만들어야합니다.

그렇다면 사용자가 확인 버튼을 클릭 할 때까지 입력란의 유효성 검사를 어떻게 지연합니까? 당신의 도움을 주셔서 감사합니다.

답변

0

데이터 바인딩에는 UpdateSourceTrigger 속성이 있습니다. 이름에서 알 수 있듯이 바인딩 원본을 업데이트 할시기를 지정합니다. Text 속성의 경우 기본적으로 LostFocus로 설정됩니다. 이것을 명시 적으로 설정하고 코드에서 BindingExpression의 UpdateSource 메서드를 호출 할 수 있습니다. 한편, PropertyChanged 이벤트의 발생을 연기 할 수도 있습니다. 그러나 이것들은 응용 프로그램 실행시 유효성 검사의 문제를 해결하지 못할 것이라고 생각합니다. 희망이 어떻게 든 도움이됩니다.

+0

부분적인 해결책입니다. 제출할 때까지 데이터 바인딩이 업데이트되지 않습니다. 그러나 도움을 주시면 고맙겠습니다. 바인딩을 동기화 된 상태로 유지하면서 페이지 제출까지 유효성을 유지하는보다 복잡한 해결책을 자세히 설명했습니다. –

7

마이클이 도와 주신 덕분입니다. 불행히도, 바인딩은 유효성 검사가 지연된 상태로 지속적으로 동기화되도록 유지해야합니다. 그렇지 않으면, 마이클의 해결책이 그 일을 할 것입니다. 그래서 저는 약간 다른 방향으로갔습니다. 여기 제가 궁극적으로 구현 한 해결책이 있습니다.

간단한 데모 : 가장 간단한 경우부터 시작해 보겠습니다. 내 비즈니스 객체는 IDataErrorInfo을 구현합니다. 구현 방법을 수정할 수 있다고 가정 해 보겠습니다. 각 비즈니스 객체에 ValidationEnabled이라는 부울 속성을 추가하고 해당 속성이 false 인 경우 항상 null 결과를 반환하도록 IDataErrorInfo 구현을 수정합니다.

본인의 원래 게시물에서 언급 한 데모는 두 개의 속성이있는 Contact 객체를 사용합니다. 이름과 성. 나는 ValidationEnabled 속성을 추가하고 IDataErrorInfo 구현은 다음과 같습니다 수정 :

간단한 데모의 내 버전에서
#region IDataErrorInfo Members 

public string Error 
{ 
    get { throw new System.NotImplementedException(); } 
} 

public string this[string columnName] 
{ 
    get 
    { 
     // Initialize 
     string result = null; 

     // Perform validation only if enabled 
     if (ValidationEnabled) 
     { 
      switch (columnName) 
      { 
       // Validate 'First Name' 
       case "FirstName": 
        if (string.IsNullOrEmpty(FirstName)) 
        { 
         result = "First name has to be set"; 
        } 
        else if(FirstName.Length < 5) 
        { 
         result = "First name must be at least five characters"; 
        } 
        break; 

       // Validate "Last Name" 
       case "LastName": 
        if (string.IsNullOrEmpty(LastName)) 
        { 
         result = "Last name has to be set"; 
        } 
        else if (LastName.Length < 5) 
        { 
         result = "Last name must be at least five characters"; 
        } 
        break; 
      } 
     } 

     // Set return value 
     return result; 
    } 
} 

#endregion 

, 나는 검증을 가능하게하고 대한 바인딩을 새로 고쳐 코드 숨김에서 이벤트 처리기에 제출 버튼을 연결 두 텍스트 상자 :

private void OnButtonClick(object sender, RoutedEventArgs e) 
{ 
    var contact = (Contact) DataContext; 
    contact.ValidationEnabled = true; 
    var binding = FirstNameBox.GetBindingExpression(TextBox.TextProperty); 
    binding.UpdateSource(); 
    binding = LastNameBox.GetBindingExpression(TextBox.TextProperty); 
    binding.UpdateSource(); 
} 

이제 양식을 제출할 때까지 빨간색 외곽선이 표시되지 않습니다.

현실 세계 : 내 프로덕션 응용 프로그램에서는 비즈니스 개체를 제어하지 않으며 간단한 데모 에서처럼 비즈니스 개체를 수정할 수 없습니다. 따라서 뷰에 데이터 바인딩 될 특성을 표시하고 랩핑 된 Business Object의 해당 특성에 해당 특성을 링크하는 Business Object에 대한 간단한 pass-through wrapper를 작성합니다. 래퍼는 IDataErrorInfo를 구현하고 ValidationEnabled 속성을 포함합니다.

유효성 검사를 사용하지 않으면 래퍼의 IDataErrorInfo 구현은 항상 null을 반환합니다. 유효성 검증이 사용 가능한 경우, 랩퍼는 랩핑 된 오브젝트에 대해 IDataErrorInfo 구현을 호출하고 그 오브젝트에서 가져온 내용을 리턴합니다.

이 접근법은 Model-View-ViewModel 패턴을 사용하는 모든 사용자에게 익숙 할 것입니다. 우리가하고있는 일은 많은 개발자들이 MVVM 베스트 프랙티스로 생각하는 비즈니스 객체에 대한 뷰 모델 래퍼를 만드는 것입니다. 비즈니스 모델 관심사 (간단한 객체 유효성 검사)에서 UI 관심사 (페이지가 제출 될 때까지 빨간색 경계선 유지)를 구분합니다.

또한 제작 용 앱은 코드 숨김에서 이벤트 처리기를 사용하지 않습니다. MVVM 단위로 단추는 간단한 데모에서 OnButtonClick() 핸들러의 논리를 포함하는 ICommand에 연결됩니다.

이 문제를 연구하는 다른 사람들에게 도움이되기를 바랍니다.

+0

감사합니다 ... 그것은 나를 위해 아주 잘 작동하고 있습니다. – danjarvis

관련 문제