2011-02-11 6 views
1

현재 IDataErrorInfo 인터페이스를 사용하여 WPF 응용 프로그램에서 유효성 검사를 구현하고 있습니다. 그 인터페이스의 일부입니다 인덱서과 같이, 하나의 속성을 확인 할 수 있습니다 : 유효성 검사 오류가 나는 옆에있는 텍스트 상자에 도구 설명에 별표 (*) 표시가 발생WPF에서 교차 속성 유효성 검사

public string this[string columnName] 
{ 
    get 
    { 
     switch (columnName) 
     { 
      case "LastName": 
       if (string.IsNullOrEmpty(this.LastName)) 
        return "LastName must not be empty."; 
       break; 
      // case, case, case, etc., etc. 
     } 
     return null; 
    } 
} 

합니다.

하나의 속성과 엄격하게 관련이없는 유효성 검사 규칙을 가지고 있다면 어떻게해야합니까? 예를 들어 주문을 나타내는 도메인 엔터티에 출고 날짜와 송장 날짜가 있고 인보이스 일자가 배송일 이후 여야한다는 규칙을 확인하려면 어떻게해야합니까?

물론이 관계식을 columnName "ShippingDate"에 대해 한 번, columnName "InvoiceDate"에 대해 한 번씩 두 번 확인하여이 규칙을 강제로 인덱서에 적용한 다음 UI의 입력 필드에 별표가있는 오류를 표시 할 수도 있습니다 그래서 같은 :

public string this[string columnName] 
{ 
    get 
    { 
     switch (columnName) 
     { 
      case "ShippingDate": 
      case "InvoiceDate": 
       if (this.ShippingDate > this.InvoiceDate) 
        return "Invoice date must not be before shipping date."; 
       break; 
     } 
     return null; 
    } 
} 

하지만 인덱서 (인덱서는 무효 "하나의 속성 상태"를보고해야합니다)에서 "개체 수준"또는 독립적으로 "크로스 부동산"검증을 선호하고 그 객체를 표시 할 것 수준 또는 관계 오류를 UI에 별도로 표시합니다.

IDataErrorInfo 인터페이스의 Error 속성이 개체 수준 유효성 검사의 목적을 갖고 있기를 바랬습니다. 예를 들어 WPF는 TextBox의 Binding 표현식에 ValidatesOnDataErrors=True을 지정할 때 속성 유효성 검사를 위해 인덱서를 호출합니다. 그러나 입력 필드에서 일부 데이터를 변경할 때마다 Error 속성을 호출하도록 WPF에 지시 할 수있는 방법을 찾지 못했습니다. 어쩌면이 부동산의 목적에 대한 내 추측이 틀렸을까요?

WPF에서 교차 속성 유효성 검사를 어떻게 구현할 수 있습니까?

미리 감사드립니다. 내 질문에 대해서는

답변

2

경우 I 수를 셋업 WPF가 자동으로 나는 다음과 같은 부정적인 대답 here있는 IDataErrorInfo 인터페이스의 Error 특성 테스트 있도록 바인딩 : 사람으로부터

질문 : 기본적으로

을, I 에있는 IDataErrorInfo.Error 테스트를 트리거하는 바인딩 속성 ValiditesOnDataErrors 은 의 테스트를 발생시킵니다. IDataErrorInfo.Item. Microsoft 온라인 커뮤니티 지원에서

답변 :

바인딩 클래스의 ValidatesOnDataErrors 속성을 설정

만 IDataErrorInfo.Item의 테스트 및 하지 IDataErrorInfo.Error의.

바인딩 클래스는 지금까지 확인 IDataErrorInfo.Item에 ValidatesOnDataErrors 속성으로 IDataErrorInfo.Error을 확인하는 속성을 제공하지 않습니다.

는 그래서, Error 속성은 내 자신을 정의하는 것보다 더 값이없는 ... 요 우리가 데이터를 IDataError.Error에 바인딩 를 설정해야, 원하는 것을 얻으려면 도메인 엔터티에 수작업으로 만든 속성 (예 : CrossPropertyErrors) WPF는 쉬운 기본 제공 방식으로 Error 속성 테스트를 지원하지 않습니다.

편집 : 위의 인용문은 2008 년 3 월 이후로, .NET 3.5와 관련이있을 가능성이 큽니다. 하지만 .NET 4.0에서 이것이 바뀌 었다는 어떤 징후도 발견 할 수 없었습니다.

편집 : 마지막으로 Error 속성에 직접 작성한 바인딩을 만들고 적절한 교차 속성 오류 메시지로 채워야했습니다. 클래스의 다른 속성을 변경할 때마다 PropertyChanged 변경된 속성 자체와 Error 속성의 이벤트가 발생하여 UI에서 오류 메시지를 새로 고칩니다.

편집 2

그것은 다음과 같이 대략 같습니다

모델 (또는 뷰 모델) 클래스 :

public class SomeModel : NotificationObject, IDataErrorInfo 
{ 
    private string _someProperty; 
    public string SomeProperty 
    { 
     get { return _someProperty; } 
     set 
     { 
      if (_someProperty != value) 
      { 
       _someProperty = value; 
       RaisePropertyChanged("SomeProperty", "Error"); 
       // That's the key: For every changed property a change 
       // notification also for the Error property is raised 
      } 
     } 
    } 
    // The above repeats for every property of the model 

    #region IDataErrorInfo Member 
    public string Error 
    { 
     get 
     { 
      var sb = new StringBuilder(); 
      // for example... 
      if (InvoiceDate < ShippingDate) 
       sb.AppendLine("InvoiceDate must not be before ShippingDate."); 

      // more cross-property validations... We have only one Error 
      // string, therefore we append the messages with 
      // sb.AppendLine("Another message...") ... etc. 
      // could all be moved into a separate validation class 
      // to keep the model class cleaner 

      return sb.ToString(); 
     } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
      switch (columnName) 
      { 
       case "ShippingDate": 
        // property-level validations 
       case "InvoiceDate": 
        // property-level validations 
       // etc. 
      } 
      return null; 
     } 
    } 
    #endregion 
} 

NotificationObjectRaisePropertyChanged 구현 : A의 다음

public abstract class NotificationObject : INotifyPropertyChanged 
{ 
    #region INotifyPropertyChanged Member 
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 

    protected virtual void RaisePropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    protected void RaisePropertyChanged(params string[] propertyNames) 
    { 
     if (propertyNames == null) 
      throw new ArgumentNullException("propertyNames"); 

     foreach (var name in propertyNames) 
      RaisePropertyChanged(name); 
    } 

    // ... 
} 

경쟁하다 예를 들어 - - Error 속성에 바인딩 승 교차 속성 유효성 검사 오류 표시하는 TextBlock : 그래서

<TextBlock Text="{Binding SomeModel.Error}" TextWrapping="Wrap" ... /> 

:의 (잠재적 인) 변화에 대한 WPF 바인딩 엔진을 알립니다 모델에 대한 모든 변경 속성을 Error 속성은 교차 속성 유효성 검사 텍스트의 업데이트를 유발합니다.

+0

여기에 일부 소스 코드를 제공 할 수 있습니까? 나는 같은 문제를 겪고있다 ... – Rob

+0

@Rob : 나는 그 물건들이 어떻게 생겼는지 간단한 스케치를 추가했다. 위의 편집 2를 보아라. – Slauma

관련 문제