2011-08-19 8 views
17

저는 StartDate와 EndDate라는 두 개의 날짜 필드가 있습니다. StartDate는 EndDate보다 이전이어야합니다.여러 속성 중 하나가 변경되면 어떻게 유효성을 검사합니까?

사용자가 StartDate를 EndDate보다 큰 값으로 변경하면 해당 DatePicker 주위에 빨간색 테두리가 나타나고 그 반대의 경우도 마찬가지입니다. 사용자가 두 번째 상자를 변경하여 날짜 범위가 올바르면 첫 번째 상자에는 유효성 검사 오류가 계속 표시됩니다.

두 날짜 필드 중 하나가 변경되면 어떻게 확인합니까? 나는 그들 중 하나가 그래서 PropertyChange 이벤트를 마련 둘 다 가지고, 변경할 때 두 필드의 유효성을 검사 할 필요가 있기 때문에 단순히 PropertyChange 이벤트를 발생시킬 수 없습니다 IDataErrorInfo

public string GetValidationError(string propertyName) 
{ 
    switch (propertyName) 
    { 
     case "StartDate": 
      if (StartDate > EndDate) 
       s = "Start Date cannot be later than End Date"; 
      break; 

     case "EndDate": 
      if (StartDate > EndDate) 
       s = "End Date cannot be earlier than Start Date"; 
      break; 
    } 

    return s; 
} 

을 사용하고

enter image description here

다른 하나는 무한 루프에 걸릴 것입니다.

다른 날짜가 유효성 검사 오류를 반환하면 날짜 필드를 지우는 아이디어도 좋지 않습니다.

+0

대체 방법을 사용하면 두 규칙 중 하나가 잘못되었을 때 빨간색으로 표시 될 수 있습니까? 그렇다면 하나의 propertychanged 이벤트 만 올리면됩니다. – Josh

+0

@ Josh는 좋아 하겠지만 개별 속성에 대한 유효성 검사 이벤트를 수동으로 발생시키는 방법을 모르겠습니다. – Rachel

+0

유효성 검사 이벤트를 사용하여 종료합니다.나는 그들이 화재를 당해야한다고 생각하는 곳에서 그들과 너무 많은 문제를 겪었고, 화재가 발생하지 않았거나 화재가 발생하고 국경이 강조 표시되지 않습니다. 유효한 BOOLEAN 표현에 바인딩 된 Red Border 스타일을 사용합니다. 또한 툴팁을 메시지 속성에 바인딩합니다. 그런 다음 값이 변경되면 유효성을 검사하고 속성을 적절하게 설정합니다. – Josh

답변

14

가장 간단한 방법은 그 당신을 위해 작동하지 않는 경우 bathineni suggests

private DateTime StartDate 
{ 
    get { return _startDate; } 
    set 
    { 
     if (_startDate != value) 
     { 
      _startDate = value; 
      RaisePropertyChanged("StartDate"); 
      RaisePropertyChanged("EndDate"); 
     } 
    } 
} 

private DateTime EndDate 
{ 
    get { return _endDate; } 
    set 
    { 
     if (_endDate!= value) 
     { 
      _endDate= value; 
      RaisePropertyChanged("StartDate"); 
      RaisePropertyChanged("EndDate"); 
     } 
    } 
} 

처럼 검증해야 할 두 속성에 대한 세터에 대한 PropertyChanged 통지를 인상하는 것입니다, 나는 한 가지 방법을 알아 냈 수업은 (필자는 두 인터페이스를 구현 EntityFramework 기본적으로 자신의 클래스를 사용하고 있습니다)

확장 메서드

01,235 INotifyPropertyChanged에 추가 INotifyPropertyChanging을 구현해야하지만, 함께 속성 그룹을 확인
public static class ValidationGroup 
{ 
    public delegate string ValidationDelegate(string propertyName); 
    public delegate void PropertyChangedDelegate(string propertyName); 

    public static void AddValidationGroup<T>(this T obj, 
     List<string> validationGroup, bool validationFlag, 
     ValidationDelegate validationDelegate, 
     PropertyChangedDelegate propertyChangedDelegate) 
     where T : INotifyPropertyChanged, INotifyPropertyChanging 
    { 

     // This delegate runs before a PropertyChanged event. If the property 
     // being changed exists within the Validation Group, check for validation 
     // errors on the other fields in the group. If there is an error with one 
     // of them, set a flag to true. 
     obj.PropertyChanging += delegate(object sender, PropertyChangingEventArgs e) 
     { 
      if (validationGroup.Contains(e.PropertyName)) 
      { 
       foreach(var property in validationGroup) 
       { 
        if (validationDelegate(property) != null) 
        { 
         validationFlag = true; 
         break; 
        } 
       } 
      } 
     }; 

     // After the Property gets changed, if another field in this group was 
     // invalid prior to the change, then raise the PropertyChanged event for 
     // all other fields in the Validation Group to update them. 
     // Also turn flag off so it doesn't get stuck in an infinite loop 
     obj.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) 
     { 
      if (validationGroup.Contains(e.PropertyName)) 
      { 
       if (validationFlag && validationDelegate(e.PropertyName) == null) 
       { 
        validationFlag = false; 
        foreach(var property in validationGroup) 
        { 
         propertyChangedDelegate(property); 
        } 
       } 
      } 
     }; 
    } 
} 

사용하려면 속성 그룹을 함께 확인해야하는 모든 클래스의 생성자에 다음 호출을 추가하십시오.

this.AddValidationGroup(
    new List<string> { "StartDate", "EndDate" }, 
    GetValidationError, OnPropertyChanged); 

유효성 검사 그룹에서 최대 3 개의 속성을 테스트했으며 정상적으로 작동하는 것 같습니다.

+0

나는 너와 똑같은 문제를 겪고있다. INotifyPropertyChanging 솔루션을 사용 했습니까? 아니면 다른 방법을 찾았습니까? –

+0

@ Björn 인터페이스가 이미 Entity Framework에 의해 구현 되었기 때문에이 경우에는 INotifyPropertyChanging을 사용했습니다. 그렇지 않다면, 아마도 방금 관련된 속성의'set' 메소드에서 PropertyChanged 이벤트를 발생 시켰을 것입니다. – Rachel

+0

정보를 제공해 주셔서 감사합니다. StartDate> EndDate if EndDate = StartDate를 설정하면 유효성 검사가 제거되고 코드가 변경되었습니다. 모든 사람이 할 수있는 일은 아니지만 제 경우에는 적합합니다. –

0

나는 일반적으로 모든 유효성 검사 오류를 사전에 추가하고 유효성 검사 템플릿을 속성 이름을 통해 구독하도록합니다. 각 속성 변경 이벤트 처리기에서 필요한 수만큼 속성을 확인하고 필요에 따라 유효성 검사 상태를 추가하거나 제거 할 수 있습니다.

내 구현의 모양은 this answer을 확인하십시오. 죄송합니다 그것은 VB.NET에 있지만 매우 간단해야합니다.

2

사용이 트릭은, 그들이 서로를 OnPropertyChanged를 호출 방지 :

private bool RPCfromStartDate = false; 
private bool RPCfromEndDate = false; 

public string this[string columnName] 
{ 
    get 
    { 
       string result = null; 
       switch (columnName) 
       { 
        case "StartDate": 
         if (StartDate.Date >= EndDate.Date) 
         { 
          result = "Start Date cannot be later than End Date"; 
         } 
         if (!RPCfromEndDate) 
         { 
          RPCfromStartDate = true;        
          OnPropertyChanged("EndDate"); 
          RPCfromStartDate = false; 
         } 
        case "EndDate": 
         if (StartDate.Date >= EndDate.Date) 
         { 
          result = "End Date cannot be earlier than Start Date"; 
         } 
         if (!RPCfromStartDate) 
         { 
          RPCfromEndDate = true;        
          OnPropertyChanged("StartDate"); 
          RPCfromEndDate = false; 
         } 
         break; 
       } 
... 
-1

또한 바인딩 필요한 SelectedDateChanged 이벤트 핸들러 및 업데이트에 가입 할 수 있습니다.

BindingExpression expression = datePickerStartDate.GetBindingExpression(DatePicker.SelectedDateProperty); 
if (expression != null) 
{ 
    expression.UpdateSource(); 
} 
+0

나는 내 질문에 말했듯이, 두 개의 날짜가 있기 때문에 이것이 작동하지 않으므로 무한 루프에 걸릴 것입니다. – Rachel

+0

나는 당신을 혼란스럽게하고있다. startDate가 변경되면 EndDate 바인딩을 업데이트합니다 (유효성 검사 만 수행되며 변경되지 않습니다). endDate가 변경되면 StartDate 바인딩을 업데이트합니다. 무한 루프가 발생하지 않아야합니다. –

관련 문제