2011-09-26 3 views
0

잠시 전에 UI와 비즈니스 계층 상호 작용을 처리하는 좋은 방법을 찾고있는이 SO post을 작성했으며 MVVM 패턴을 사용하는 답이 마음에 들었습니다.MVVM 패턴을 사용할 때 WPF에서 Windows 제어하기

이렇게 나는 아주 성공적으로했지만이 패턴을 사용하는 데 문제가 있습니다. 사실, 내 UI의 일부에서 내 버튼 중 하나는 ListView에 표시된 항목의 세부 정보가있는 대화 상자를 여는 것으로되어 있습니다.

저는이 SO post에 대해 같은 질문을했지만, 답을 이해하지 못했고 제 경우에 적합할지 궁금합니다. 아이디어는 Unity 프레임 워크를 사용하고 예를 들어 App.Container.Resolve<MyChildView>().ShowDialog()을 사용하여 저장소의보기와 연결된 창을 호출하는 것이 었습니다.

그러나 내 문제는 UI 클라이언트 프로젝트와 별도로 프로젝트에서 ViewModels을 구현 한 것입니다. 프로젝트의 나중 단계에서 필요할 경우 다른 클라이언트의 VM을 사용할 수 있도록하기 위해이 작업을 수행했습니다. 첫 번째 질문은 잘못된 패턴 구현 이었습니까?

두 번째 질문은 내 ViewModels 프로젝트가 실제로 클라이언트 프로젝트에 없으므로 App 전역 변수에 액세스 할 수 없기 때문입니다. 따라서 이전에 언급 한 게시물에서 찾은 솔루션을 사용할 수 있다고는 생각하지 않습니다. 해결 방법이 있습니까?

답변

0

시도해보십시오. 새 스레드를 설정하고 창을 초기화하고 표시하십시오 (Show() 대신 ShowDialog()을 사용할 수도 있음). 을 호출하여 스레드를 UI 스레드로 변환하면 창이 닫힐 때까지 차단됩니다. 그런 다음 나중에 대화 상자 결과를 처리 할 수 ​​있습니다.

new Thread(() => 
{ 
    MyDialogWindow m = new MyDialogWindow(); 
    m.ShowDialog(); 
    Dispatcher.Run(); 
    // Handle dialog result here. 
}).Start(); 

하면 디스패처 정지를 가지고, 당신은 창을 닫으면 대한 대화 상자에서 이벤트를 추가해야합니다. 대화 상자의 생성자에 다음을 추가하십시오.

Closed += (_,__) => Dispatcher.InvokeShutdown(); 
+1

하지만 이것은 VM 내에서 뷰를 참조하는 것을 의미 할 것입니다. 이는 패턴의 아이디어와 상반됩니다. – SRKX

+0

뷰 모델에서 참조하지 마십시오. 별도의 클래스를 작성하여 대화 상자 창에서 값을 리턴하십시오. – qJake

1

1) 구현에 문제가 전혀 없습니다. 필자는 UI, VM 및 모델을 별도의 어셈블리로 정기적으로 분리합니다.

2) 언급 한 바와 같이, VM 내에서 App을 참조하는 것은 적절하지 않습니다. App에 "UI 클래스"를 고려하고 이와 같이 취급하십시오. VM에 적절한 UnityContainer를 주입하는 것을 고려 했습니까?

컨테이너를 삽입 할 수없는 경우 솔루션에 컨트롤러를 추가하거나 언급 한 SO post의 다른 답변에서 제안한대로 중재자 패턴을 사용하는 것이 좋습니다.

+0

다른 포스트에서 컨트롤러를 사용하면 모델 뷰에 대한 뷰의 참조를 제공하는 한 MVVM 패턴을 "손상"시킬 수 있습니다. 유니티 컨테이너에 관해서는 뷰를 참조하지 않고 MV에 어떻게 삽입 할 수 있습니까? – SRKX

+0

@SRKX, 나는 컨트롤러가 MVVM을 깨뜨리는 것에 동의하지 않습니다. 보통 인터페이스 (VM 어셈블리 또는 공통 어셈블리에 정의 된 IController)를 구현하는 UI 클래스 어셈블리에 Controller 클래스를 추가합니다. 내 VM에 IController가 주입됩니다. 컨트롤러에서 UI 어셈블리에 대한 종속성을 생성하는 멤버를 노출하고 싶지는 않습니다. 예를 들어, MyChildView 멤버를 공개하지 말고, 원하는 작업을하는 메소드를 노출하십시오. – RMart

+0

디커플링과 함께 극단적으로 가야하고 구체적인 UI 클래스에 결합 된 컨트롤러의 아이디어가 마음에 들지 않으면 뷰에 인터페이스를 구현하는 것이 좋습니다. '_injectedContainter.Resolve (). ShowDialog()'를 실행하는 VM이나 컨트롤러에는 아무런 문제가 없습니다. – RMart

관련 문제