2016-12-14 5 views
-1

MVVM 패턴 및 바인딩 컬렉션에 문제가 있습니다. 내 뷰 모델은보기에 모음을 제공하지만이를 사용하는이 컬렉션을 얻을 : 나는 그들이 동일한 기준을 사용하기 때문에 내가 모델에 직접 내보기를 결합하는 경우로의이 목록에 내보기를 결합MVVM 및 비즈니스 논리 레이어

public BindingList<Car> BindingListCars { get; set; } 

public CarsVm() 
{ 
    BindingListVoiture = carServices.ListCars; 
} 

. 따라서 Car 중 하나의 속성을 편집 할 때 carServices 유효성 검사 방법을 사용하지 않고 모델을 직접 편집합니다.

이 문제를 해결하는 가장 좋은 해결책은 무엇입니까?

내 모델을보기에서 직접 편집하지 않으려면 내 모델 사본을 내보기에 노출해야합니까?

내 모델에 BindingList을 사용하고 ListChanged에 내 carServices에 서브을 적용해야 각 변경 사항의 유효성을 검사 할 수 있습니까?

+0

[컬렉션을 사용하여 MVVM을 구조화하려면 어떻게합니까?] (http://stackoverflow.com/questions/7178801/how-do-i-structure-mvvm-with-collections) –

+0

Google "mvvm 모음집"을 사용하면 많은 토론과 유용한 솔루션을 찾을 수 있습니다. –

답변

1

"실제"Car 개체를보기에 표시하는 대신 Car 클래스 자체에서 직접 유효성 검사를 수행하거나 래퍼 개체를 노출해야합니다.

다음 샘플 코드는 무슨 뜻인지에 대해 당신에게 아이디어를 줄 것이다 : 분명히

//the "pure" model class: 
public class Car 
{ 
    public string Model { get; set; } 
} 


public class CarService 
{ 
    public List<CarWrapper> ListCar() 
    { 
     List<Car> cars = new List<Car>(); //get your Car objects... 

     return cars.Select(c => new CarWrapper(c, this)).ToList(); 
    } 

    public bool Validate() 
    { 
     // 
     return true; 
    } 
} 

public class CarWrapper 
{ 
    private readonly Car _model; 
    CarService _service; 
    public CarWrapper(Car model, CarService service) 
    { 
     _model = model; 
     _service = service; 
    } 

    //create a wrapper property for each property of the Car model: 
    public string Model 
    { 
     get { return _model.Model; } 
     set 
     { 
      if(_service.Validate()) 
       _model.Model = value; 
     } 
    } 
} 

을보기가 결합하는 당신이 당신의 뷰 모델에서 IEnumerable을 < 자동차 >을 노출하는 경우, 당신은 효과적으로 유효성 검사를 우회하는 뷰가 Car 클래스의 속성을 설정할 수있는 경우 Car 클래스 외부에 전용으로 지정됩니다. 당신의 응답 MM8에 대한

0

감사합니다, 나는 외부 검증이 필요 클래스 당 하나 개의 랩퍼를 작성해야이 솔루션을

. 작업을 추가하고 리팩토링하는 동안 클래스와 래퍼를 편집해야합니다.

  • 내 서비스가
  • INotifyDataErrorInfo를 구현 내가 바인딩 목록에 차량의 내 목록을 넣어

    1. 내 서비스가이 목록의 ListChanged 이벤트에 가입 :

      당신이 솔루션에 대해 어떻게 생각하십니까 이 목록의 각 수정에 대해 유효성 검사가 수행됩니다.

    2. 오류가있는 경우 ErrorsChanged 이벤트 발생 뷰 모델이이 짝수 t 및 오류 데이터를 검색하십시오.
    3. 뷰 모델이이 이벤트에 종속되어 오류 데이터를 검색합니다. 예를 들어

    :

    내 서비스 구현 :

    public class VehicleServices : INotifyDataErrorInfo 
    { 
    
        private BindingList<Vehicle> _bindingListCar 
        public BindingList<Vehicle> BindingListCar 
        { 
         get return _bindingListCar; 
        } 
    
        private readonly Dictionary<string, ICollection<string>> 
         _validationErrors = new Dictionary<string, ICollection<string>>(); 
    
        //INotifyDataErrorInfo implementation 
    
        public IEnumerable GetErrors(string propertyName) 
        public bool HasErrors 
        private void RaiseErrorsChanged(string propertyName) 
    
        public VehicleServices() 
        { 
         _bindingListCar = GetVehicles(); 
         _bindingListCar.ListChanged += BindingListVehicleChanged; 
        } 
    
        private void BindingListVehicleChanged(object sender, ListChangedEventArgs e) 
        { 
         //Only modification is managed 
         if (e.ListChangedType != ListChangedType.ItemChanged) return; 
         switch(e.PropertyDescriptor.Name) 
    
         //Validate each property 
    
         //if there is ErrorsChanged is raised 
        } 
    } 
    

    그리고 내 뷰 모델

    public class CarVm : BindableBase 
    { 
    
         private ICollection<string> _errors; 
    
         public ICollection<string> Error 
         { 
         get 
         { 
          return _errors; 
         } 
         set 
         { 
          SetProperty(ref _errors, value); 
         } 
         } 
         private VehicleServices _carServices; 
    
         public BindingList<Vehicle> BindingListCar { get; set; } 
    
         public CarVm(VehicleServices carServices) 
         { 
          _carServices = carServices; 
          BindingListCar = new BindingList<Vehicle>(_carServices.BindingListCar); 
          _carServices.ErrorsChanged += _carServices_ErrorsChanged; 
         } 
    
         private void _carServices_ErrorsChanged(object sender, DataErrorsChangedEventArgs e) 
         { 
          Error = _carServices.ValidationErrors[e.PropertyName]; 
         } 
    } 
    

    이 좋은 방법입니다 생각합니까?

  • +0

    뷰 모델 컨트롤이며 INotifyDataError 인터페이스를 구현해야하는 서비스는 아닙니다. – mm8