2010-05-25 7 views
1

도메인 모델 컬렉션 (일반적으로 List 또는 IEnumerable)은 이고 ViewModel에는이 위임되었습니다.WPF/MVVM : 도메인 모델 컬렉션을 ViewModel로 위임

Thats는 내 CustomerViewModel에 List 또는 IEnumerable 유형의 주문 모음이 있음을 의미합니다.

목록의 변경 내용이 바운드 컨트롤에서 인식되지 않습니다. 하지만 ObservableCollection에서는 그렇습니다.

이것은 MVVM 디자인 패턴의 문제입니다.

어떻게 대처합니까?

UPDATE : 나는 그것을 할 방법 샘플 : 나는 당신이 설명하는 방법을 수행하지 않음으로써이 처리

public class SchoolclassViewModel : ViewModelBase 
{ 
    private Schoolclass _schoolclass; 
    private ObservableCollection<PupilViewModel> _pupils = new ObservableCollection<PupilViewModel>();   

    public SchoolclassViewModel(Schoolclass schoolclass) 
    { 
     _schoolclass = schoolclass; 
     _schoolclass.Pupils = new List<Pupil>(); 

     foreach (var p in schoolclass.Pupils)   
      Pupils.Add(new PupilViewModel(p));    
    } 

    public Schoolclass GetSchoolclass 
    { 
     get { return _schoolclass; } 
    } 

    public int ID { get; set; }  

    public string SchoolclassName 
    { 
     get { return _schoolclass.SchoolclassName;} 
     set 
     { 
      if(_schoolclass.SchoolclassName != value) 
      {      
       _schoolclass.SchoolclassName = value; 
       this.RaisePropertyChanged("SchoolclassName"); 
      } 

     } 
    } 

    public ObservableCollection<PupilViewModel> Pupils 
    { 
     get{ return _pupils;} 
     set 
     { 
      _pupils = value; 
      this.RaisePropertyChanged("Pupils"); 
     } 
    } 
} 
+2

MVVM 디자인 패턴에는 어떤 문제가 있습니까? 목록의 변경 사항은 수집이 관찰 가능한 경우에만 인식됩니다. 이것은 MVVM뿐만 아니라 모든 프로그래밍입니다. –

+1

MVVM 디자인 패턴만으로 모델을 뷰 모델에 위임하기 때문에 일반적인 문제는 아닙니다. 도메인 모델/컬렉션은 데이터 바인딩에서 변경 알림을위한 ObservableCollection을 갖는 ViewModel 요구 사항과 독립적으로 개발되어야합니다. ViewModel (컬렉션이 UI 요구 사항 인 경우 알림)과 모델 (모델이 뷰에 바인딩되어 있지 않기 때문에 변경 알림이 전혀 표시되지 않습니다.) – msfanboy

+0

ObservableCollection 을 IEnumerable 이며 기본 유형이 ObservableCollection 인 경우 바인딩이 여전히 예상대로 작동하지만 맞습니까? (나는 이것이 옳다고 생각하지만, 지금은 정말로 기억하지 못한다.) – ckramer

답변

0

좋아, 이제 답장으로 대답 대신 내 생각을 추가하겠습니다. :)

결론이게 WPF와 데이터 바인딩 작업의 현실에 불과하다고 생각합니다. 양방향 데이터 바인딩이 작동하려면 컬렉션에 바인딩 된 컨트롤을 알리는 수단이 필요하며 대부분의 도메인 개체에 사용되는 표준 목록 및 컬렉션은이를 지원하지 않으며/지원하지 않아야합니다. 주석에서 언급했듯이 비 콜렉션 속성에 대해 INotifyPropertyChanged를 구현해야하는 것은 표준 도메인 개체가 충족시키지 못하는 또 다른 요구 사항입니다.

도메인 개체는보기 모델이 아니므로 두 가지 유형의 개체간에 앞뒤로 매핑해야 할 수 있습니다. 이는 도메인 개체와 데이터 액세스 개체간에 앞뒤로 매핑하지 않아도되는 것과 유사하지 않습니다. 각 유형의 객체는 시스템에서 서로 다른 기능을 가지고 있으며 각각의 유형은 시스템에서 자신의 역할을 지원하도록 특별히 설계되어야합니다.

AOP를 사용하여 자동으로 프록시 클래스를 생성한다는 Agies의 아이디어는 매우 흥미롭고 내가 조사하려고하는 것입니다.

+1

aren't 이러한 프록시 클래스 도메인 모델의 복제본? ViewModel과 마찬가지로 도메인 모델의 클론입니다!? – msfanboy

+1

"표현"또는 "프로젝션"은 말할 수 있지만 "복제본"은 아닙니다. 위의 이유와 정확히 일치 할 수 있습니다. 도메인 객체가 DAO와 다른 관심사를 다루 듯이, 뷰 모델은 도메인 객체와 다른 관심사를 다룹니다. 경우에 따라 계층 간 필요성이 실제로 비슷하면 동일한 개체를 사용할 수도 있습니다. 예를 들어 도메인 개체에 INotifyPropertyChanged를 구현하도록 할 수 있습니다. 목록에서 양방향 데이터 바인딩을 완벽하게 지원하는 것은 더 어려울 수 있습니다 (다시, AOP를 볼 수도 있습니다). –

+0

잘 atm 나는 3 집계 도메인 모델이 있습니다. 그들은 모두 2way 데이터 바인딩, PropertyChanges 및 CollectionChanges를 지원합니다. ViewModels은 모델의 순수한 사본이므로 전혀 이해가되지 않습니다. – msfanboy

3

. 나는 Foo 객체와 뷰에 관련 Bar 객체를 제시해야하는 경우

FooViewModel은 일반적으로 유형 ObservableCollection<BarViewModel>Bars 속성을 구현하는 것입니다.

하위 Foo 클래스의 유형이 IEnumerable<Bar>Bars인지 여부에 관계없이 적용됩니다. Foo 클래스는 그렇지 않을 수도 있습니다. UI에서를 제외하고 Foo에 대한 모든 Bar 개체를 반복 할 필요가없는 애플리케이션 일 수도 있습니다. 당신이 당신의 샘플에서와

내보기 응용 프로그램의 개체 모델의 간단한 표현 편집, 나는 꽤 많은 일을. 내 생성자의 코드는 일반적으로 조금 더 간결합니다.

_Bars = new ObservableCollection<BarViewModel>(
    _Foo.Bars.Select(x => new BarViewModel(x))); 

하지만 본질적으로 같은 것입니다.

그러나 여기서는 Foo이 실제로 Bars 속성을 노출한다고 가정합니다. 그렇지 않을 수도 있습니다. 또는 일부 Bar 개체 만보기에 나타나야합니다. 또는 다른 객체와 섞여서 표시되어야하며 FooViewModelCompositeCollection을 노출해야합니다.

보기 모델은 보기의 모델입니다. 이것은 반드시 기본 객체 모델과 직접적으로 대응하지는 않습니다.

간단한 예제를 선택하십시오 : 내 프로그램은 사용자를 5 개의 다른 ListBox 컨트롤로 드래그 앤 드롭하여 항목을 5 가지 카테고리로 분류 할 수있는 방법을 제공합니다. 궁극적으로이 작업을 수행하면 Item 개체의 Category 속성이 설정됩니다. 내 뷰 모델은 CategoryViewModel 개체 컬렉션을 가지며 각 개체는 ObservableCollection<ItemViewModel> 유형의 속성을 가지므로 컬렉션간에 항목을 앞뒤로 끌어 놓기가 간단합니다.

것은이도 , 응용 프로그램의 개체 모델에 Category 클래스가 혼자 Category 개체의 컬렉션을 못하게 할 수있다. Item.Categorystring 유형의 자산 일 수 있습니다. CategoryViewModel은 응용 프로그램의 개체 모델을 미러링하지 않습니다. UI에서보기를 지원하기 위해서만 존재합니다.

+0

@Robert 귀하의 의견은 동시에 나에게 흥미와 혼란 소리. 초기 질문을 코드 샘플로 업데이트했습니다. 내 샘플을 어떻게 든 설명 할 수 있습니까? – msfanboy

+2

@Robert : 난 당신이/설명 무엇 모든 것을 이해하지 못하는 당신이 때마다 당신이 당신의 ViewModel에 도메인 모델에서 컬렉션을 사용하려는 그의 불만을 확인 생각, 당신은에 그것을 프로젝트가 ObservableCollection (그리고 당신이 그것을 저장하는 것과 같은 것을하고 싶다면 그것을 다시 투영하십시오). –

+1

예. 그러나 불만은 실제로 "나는 사소한 사용자 인터페이스를 제공하고 싶습니다. 내 도메인 모델은 속성 변경 알림 및 값 변환 및 명령을 구현하지 않습니다." 도메인 모델에 해당 내용을 구현하려는 경우 도메인 모델에 뷰를 결합하면 오히려 원하지 않는 많은 문제가 발생한다는 것을 알게되면이를보기 모델로 리팩토링 할 수 있습니다. 뷰 모델을 만드는 것은 리팩토링을 미리 수행하는 것입니다. –

0

도메인 모델에서 ObservableCollection을 사용하는 대신 다른 유용한 표준 및 사용자 인터페이스 사이에 INotifyCollectionChanged 인터페이스를 구현하는 내 컬렉션 유형을 사용합니다. 내 생각에 Rockford Lhotka은 도메인 계층 내의 다른 비즈니스 객체가 다른 객체의 상태가 변경 될 때 일종의 알림을 필요로하기 때문에 변경 알림이 단순한 프리젠 테이션 레이어 이상에서 유용하다는 것을 그의 책에서 제시하고 있습니다.

이 방법론을 사용하면 변경 알림의 이점과 필요한 사용자 지정 동작이있는 고유 한 컬렉션 형식을 만들 수 있습니다. 컬렉션의 기본 클래스는 순전히 인프라 코드로 구현 될 수 있으며 this book에 사용 된 하위 유형 계층화 기술을 사용하여 비즈니스 논리를 포함 할 수있는 하위 클래스를 만들 수 있습니다. 그래서 결국에는 IEnumerable <>의 유형을 래핑 할 수있는 컬렉션을 가질 수 있으며 도메인 알림과 프리젠 테이션 코드 모두에 대한 변경 알림을 제공 할 수 있습니다.