2010-04-05 2 views
17

필자는 언급 된 MVVM 패턴을 실험 해왔고 어떤 경우에는 명확한 경계를 정의하는 데 어려움을 겪어 왔습니다. 내 응용 프로그램에서는 컨트롤러에 대한 연결을 만들 수있는 대화 상자가 있습니다. 대화 상자에는 ViewModel 클래스가 있으며, 이는 매우 간단합니다. 그러나 대화 상자에는 추가 컨트롤러 (ContentTemplateSelector으로 선택)가 있습니다.이 컨트롤은 연결된 컨트롤러 유형에 따라 다릅니다. 이 컨트롤에는 자체 ViewModel이 있습니다.MVVM : 중첩 된 ViewModels 간의 상호 작용을 처리하는 방법은 무엇입니까?

내가 겪고있는 문제는 확인을 눌러 대화 상자를 닫을 때 실제로 요청 된 연결을 만들어야하는데, 이는 내부 Controller 관련 ViewModel 클래스에 캡처 된 정보가 필요합니다. 단순히 컨트롤러 고유의 ViewModel 클래스 모두가 연결을 구성하는 공통 인터페이스를 구현하도록 유혹하고 있지만 내부 ViewModel이 실제로이 구성을 담당해야합니까?

내 일반적인 질문은 ViewModel이 서로 어떻게 상호 작용해야하는지에 대한 일반적으로 받아 들여지는 디자인 패턴이 무엇인지, 특히 '부모'VM이 무엇을해야 하는지를 알기 위해 '자식'VM의 도움이 필요할 때 그렇습니까?


편집 : 나는 원래 생각했던 것보다 조금 청소기의 디자인을 마련 않았다,하지만 난 여전히이 작업을 수행 할 수있는 '권리'방법입니다 있는지 확실하지 않습니다

. ContentTemplateSelector가 컨트롤러 인스턴스를보고 연결 작성자에게 표시 할 컨트롤을 마술처럼 찾도록 허용하는 백엔드 서비스가 있습니다. 나에 대해 저를 괴롭히는 것은 최상위 수준의 ViewModel이 생성 된 컨트롤에 대해 DataContext을보고 적절한 인터페이스로 캐스팅해야한다는 것입니다. 나쁜 생각처럼 보입니다 (View의 DataContext은 ? 연결)

나는 이런 식으로 뭔가 함께 상처는() 단순화 :

public interface IController 
{ 
    IControllerConnectionBuilder CreateConnectionBuilder(); 
} 

public interface IControllerConnectionBuilder 
{ 
    ControllerConnection BuildConnection(); 
} 

나는 나의 내부 뷰 모델 클래스는 IControllerConnectionBuilder를 구현해야하고, 컨트롤러 내부 뷰 모델을 반환합니다. 그런 다음 최상위 ViewModel이 IControllerConnectionBuilder을 (가상 마법 메커니즘을 통해) 시각화합니다. 여전히 내 안의 ViewModel이 건물을 수행한다는 것을 조금은 귀찮게하지만, 적어도 현재 내 최상위 ViewModel은 더러운 세부 사항을 알 필요가 없습니다. (시각화 된 컨트롤이 ViewModel).

더 자세히 정리할 방법이 있으면 추가 생각을 환영합니다. ViewModel에 대해 '괜찮은'책임이 얼마나 많은지 아직 확실하지 않습니다.

+2

우리는 이러한 유형의 질문을 제 직업에 항상 부탁합니다. 당신은이 질문을 아주 잘 말 했으니, 여기서 좋은 피드백을 얻길 바랍니다. –

+2

고맙게도 이것은 애완 동물 프로젝트이므로 다른 디자인을 탐구하는 사치를 느낍니다. 우리 가게는 WPF 나 MVVM을 채택하지 않았습니다. 왜냐하면이 초기 단계의 오버 헤드와 어색함이 우리의 현재 일정에 맞지 않기 때문입니다. 나는이 기술을 사용하는 방법을 이해하고 나면 이것이 생산성에 큰 이익을 가져다 줄 수있는 기술이라고 강력하게 믿는다.하지만 디자인에 선을 그어야하는 곳을 아는 것은 어렵다. –

답변

3

뷰 모델 간 상호 작용에 적합한 옵션은 뷰 모델 클래스 사이에있는 observer 클래스에 직접 바인딩하는 것입니다.

+0

링크를 제공해 주셔서 감사합니다. 내 MainViewModel에 의해 구현 된 IMainViewModel 서비스를 공유하여 실제로 다른 조정을 위해 이와 비슷한 패턴을 사용하고있었습니다. 나는 그것이 "공유"기능은 메인 윈도우에 대한 모델에 묶여 있지 않고 MainObserver 인 대신 리팩토링하는 것이 더 효과적 일 것이라고 생각하고 있습니다. –

+1

이것은 유용한 접근 방법이었습니다. 내 디자인은 여전히 ​​정신 분열증이지만, VM이 공유 서비스를 사용하여 어떻게 통신 할 수 있는지보기 시작했습니다. 나는 '부모'가 그 '아이들'에 관해 모든 것을 알고 있기 때문에 익숙하지 않기 때문에 조금 뒤집어 쓴 느낌입니다. 이제는 "수업을 끝내야합니다."라는 수업의 문제와 응용 프로그램의 일부분으로 나를 강화하고 돌보는 것에 대해 거의 알지 못합니다. –

3

최상위 레벨 ViewModelNestedViewModel의 존재를 인식하고 싶다고 생각합니다. 계층 적 관점에서 볼 때 마스터보기에는 하위보기가 포함됩니다.

당신의 본능은 옳습니다. 중첩 된 ViewModel이 최상위 레벨에서 사용자 작업에 의해 시작된 동작을 노출하는 것이 정확하다고 생각하지 않습니다. 대신, 최상위 레벨 ViewModel은 연관된 뷰에 대한 동작을 제공해야합니다.

하지만 연결 구성에 대한 책임을 ICommand으로 옮기고 최상위 레벨 ViewModel을 통해이 명령을 표시하는 방법을 고려해 보겠습니다. 마스터 대화 상자의 OK 버튼을 클릭하면이 명령에 바인드되며이 명령은 최상위 레벨 ViewModel에 위임합니다. 예를 들어 실행시 ViewModel.CreateConnection()을 호출합니다.

따라서 중첩 된 컨트롤의 책임은 데이터를 포함하여 소비하기 위해 데이터를 NestedViewModel으로 수집하고 노출하는 것이고, 이론적으로 동일한 정보를 입력해야하는 다른 상황에서 재사용 가능합니다 (if any) - 이미 생성 된 연결을 편집하기 위해 다시 사용하고 싶다고 가정 해 봅시다.

다른 유형의 NestedViewModel이 근본적으로 다른 데이터 세트를 노출하는 경우에만 주름이 생길 수 있습니다.

예를 들어, 하나는 호스트 이름 및 속성으로 포트를 노출, 다른 하나는 사용자 이름비밀번호를 노출합니다.

최상위 수준의 ViewModel.CreateConnection()이 여전히 깨끗한 방식으로 작동하려면 인프라 작업을해야 할 수도 있습니다. 소량의 중첩 된 컨트롤 유형이있는 경우에는 노력할 가치가 없을 수도 있지만 간단한 NestedViewModel 형식 검사와 캐스트로 충분할 수 있습니다.

소리가 나나요?

+0

여기서 도전 과제는 외부 ViewModel이 컴파일 타임에 InnerViewModel의 유형을 실제로 알지 못한다는 것입니다. 컨트롤러는 사용자 정의 DataTemplateSelector를 통해 특정 중첩 컨트롤을 연결하기위한 몇 가지 유형 탐색과 함께 런타임에 응용 프로그램의 확장으로 가져옵니다. DataContext가 암시 적으로 중첩 된 특정 ViewModel이 될 것이라는 것을 알고 있지만, DataContext를 검사하고 공유 인터페이스로 캐스팅하려고 시도하는 것에 익숙하지 않습니다. –

0

최근 Unity (Microsoft Enterprise 라이브러리)를 사용하여 종속성 삽입을 실험했습니다. 이는 두 뷰 모델이 서로간에 필요로하지 않는 것을 완전히 정의하는 인터페이스를 사용할 때 갈 길입니다. MEF는 제가 알고있는 의존성 주입을위한 또 다른 옵션이 될 것입니다.

HTH

+0

감사합니다. 저는 실제로이 응용 프로그램에서 MEF를 사용하고 있으며 UI의 매우 풍부한 확장 성을 허용하는 데 많은 도움이되었습니다. UI가 실제로 거의 아무것도 모르는 컨트롤을 호스팅하고 있기 때문에 디자인 문제를 야기하는 확장 성입니다.저는 실제로이 일을하는 더 깨끗한 방법을 생각해 냈습니다. 나는 오늘 집에 돌아 가면 더 자세히 설명 할 것입니다. –

관련 문제