2012-07-23 4 views
1

Entity Framework 4.3에서 WPF 및 MVVM을 사용하는 프로젝트에서 작업 중이며 IDataErrorInfo 인터페이스를 구현하는 비즈니스 논리 유효성 검사를 어떻게 수행 할 수 있는지 알고 싶습니다. 그래서 원시 최대 길이, 음이 아닌 번호와 같은 검증, 등을 수행하기 위해 Entity Framework 및 IDataErrorInfo를 사용하여 비즈니스 논리 유효성 검사

내 모델 (POCO 클래스)의 모든

는에 관해서는, bussiness의 로직 검증에 대해 ...

그러나 그것을 구현하는 중복 기록 방지?

것은 내가 고유해야합니다 재료 "참조"에 대한 텍스트 상자가 상상이 좋아 정의 된 :

<TextBox Text="{Binding Material.Reference, ValidatesOnDataErrors=True, NotifyOnValidationError=true, 
           UpdateSourceTrigger=PropertyChanged}"> 

성공적으로 참조의 길이를 확인,하지만 내 뷰 모델 년대에 이미 재료가 있다면 것 모델 materials observablecollection,이 사실을 내 ViewModel에서 사용자에게 어떻게 알리고 IDataErrorInfo 메시지를 활용해야합니까?

내 ViewModels 추가 비즈니스 로직 검증에 연결할 수 있습니다 내 모델에서 검증 대리자를 노출하여 과거에 이런 짓을 한

답변

2

최종 결과는 다음과 같이 찾고 끝 :

public class MyViewModel 
{ 
    // Keeping these generic to reduce code here, but they 
    // should be full properties with PropertyChange notification 
    public ObservableCollection<MyModel> MyCollection { get; set; } 
    public MyModel SelectedModel { get; set; } 

    public MyViewModel() 
    { 
     MyCollection = DAL.GetAllModels(); 

     // Add the validation delegate to each object 
     foreach(var model in MyCollection) 
      model.AddValidationErrorDelegate(ValidateModel); 
    } 

    // Validation Delegate to verify the object's name is unique 
    private string ValidateObject(object sender, string propertyName) 
    { 
     if (propertyName == "Name") 
     { 
      var obj = (MyModel)sender; 
      var existingCount = MyCollection.Count(p => 
       p.Name == obj.Name && p.Id != obj.Id); 

      if (existingCount > 0) 
       return "This name has already been taken"; 
     } 
     return null; 
    } 
} 

대부분의 모델은이 유효성 검사 대리자를 포함하는 일반 기본 클래스에서 상속합니다. 여기이 내 모델에 기본 데이터 유효성 검사를 유지하기 위해 나를 수 Validating Business Rules in MVVM

#region IDataErrorInfo & Validation Members 

/// <summary> 
/// List of Property Names that should be validated. 
/// Usually populated by the Model's Constructor 
/// </summary> 
protected List<string> ValidatedProperties = new List<string>(); 

#region Validation Delegate 

public delegate string ValidationErrorDelegate(
    object sender, string propertyName); 

private List<ValidationErrorDelegate> _validationDelegates = new List<ValidationErrorDelegate>(); 

public void AddValidationErrorDelegate(
    ValidationErrorDelegate func) 
{ 
    _validationDelegates.Add(func); 
} 

#endregion // Validation Delegate 

#region IDataErrorInfo for binding errors 

string IDataErrorInfo.Error { get { return null; } } 

string IDataErrorInfo.this[string propertyName] 
{ 
    get { return this.GetValidationError(propertyName); } 
} 

public string GetValidationError(string propertyName) 
{ 
    // Check to see if this property has any validation 
    if (ValidatedProperties.IndexOf(propertyName) >= 0) 
    { 
     string s = null; 

     foreach (var func in _validationDelegates) 
     { 
      s = func(this, propertyName); 
      if (s != null) 
       return s; 
     } 
    } 

    return s; 
} 

#endregion // IDataErrorInfo for binding errors 

#region IsValid Property 

public bool IsValid 
{ 
    get 
    { 
     return (GetValidationError() == null); 
    } 
} 

public string GetValidationError() 
{ 
    string error = null; 

    if (ValidatedProperties != null) 
    { 
     foreach (string s in ValidatedProperties) 
     { 
      error = GetValidationError(s); 
      if (error != null) 
       return error; 
     } 
    } 

    return error; 
} 

#endregion // IsValid Property 

#endregion // IDataErrorInfo & Validation Members 

에 내 블로그의 글에서 가져온 그 기본 클래스에서 관련 코드, 그리고 내 ViewModels 그들이 원하는 모든 사용자 정의 비즈니스 로직 검증을 첨부 할 수 있습니다 모델.

+0

감사합니다. 나는 이미 사무실을 나와 있었지만 내일은 이것을 시도 할 것입니다. –

+0

잘 작동합니다! 그냥 알려주도록 코드에 다음과 같은 작은 오류가 있습니다. 목록 유형이 정의되지 않았습니다. 정의되지 않았습니다.> = 연산자가 ValidatedProperties.IndexOf (propertyName)에 없습니다. 0 –

+0

@EduardoBrites 감사합니다. 문제가 있습니다. 코드를 복사 할 때 일부 특수 문자를 제거하는 WordPress, 그래서 내가 확신 하 고 그 주말에 고정 얻을 :) – Rachel