2014-10-06 5 views
0

MVVMLight 툴킷을 사용하여 WPF 응용 프로그램을 만듭니다. "부모"양식 (ParentView)이 있고 모든 "하위"개체를로드 할 "부모"개체 (부모)를 전달하여 "자식"양식 (ChildView)을로드하려고합니다.ICommand 및 ServiceLocator를 사용하여 Parent 객체를 전달하여 MVVM 방식으로 Child 객체로드

필자는 누군가의 분석에서 중요하다고 생각하는 3 가지 기본 클래스 인 CodeModelLocation, ChildViewModel, ParentViewModel을 포함 시켰습니다. 처음에는 ParentView (아래 참조)를 인스턴스화하여 ParentViewModel 내에서 ICommand 속성을 구현할 생각 이었지만, MVVM 방식으로이 작업을 수행하려고 시도하고 있기 때문에 올바르게 보이지 않습니다. 누군가 다음과 같은 현재 구조를 어떻게 도울 수 있습니까? 어떻게 부모를 자녀에게 전달할 수 있습니까?

// ----- ChildViewModel ----- 
public class ChildViewModel 
{ 

    // this ctor doesn't make sense in the MVVM world, right?... 
    public ChildViewModel(Parent selectedParent) 
    { 
    this.Parent = selectedParent; 
    // ... 
    } 

    // how do I plug into this one?... 
    public ChildViewModel(IParentService parentService) 
    { 
    this.ParentService = parentService 
    // ... 
    } 

    // ... removed other code for brevity 
} 

// ----- ParentViewModel ----- 
{ 
    public ICommand ShowChildCommand 
    { 
    get { return new RelayCommand(() => new ChildView(SelectedParent).Show()); } 
    } 

    // ... removed other code for brevity 
} 

// ----- ViewModelLocator ----- 
public class ViewModelLocator 
{ 
    public ChildModel ChildViewModel 
    { 
    get { return ServiceLocator.Current.GetInstance<ChildViewModel>(); } 
    } 

    public ParentModel ParentViewModel 
    { 
    get { return ServiceLocator.Current.GetInstance<ParentViewModel>(); } 
    } 

    public ViewModelLocator() 
    { 
     SimpleIoc.Default.Register<IChildService, ChildService>(); 
     SimpleIoc.Default.Register<IParentService, ParentService>(); 
     // ... removed other code for brevity 
     SimpleIoc.Default.Register<ChildViewModel>(); 
     SimpleIoc.Default.Register<ParentViewModel>(); 
    } 

    // ... removed other code for brevity 
} 

// ------ 개정이 편집 ------------

나는 사용자 @kidshaw의 최신 제안을 포함하지만이에 의해 난처한 상황에 빠진했다 ParentView 내에서 ChildView의 인스턴스를 생성해야만했던 주석. 어떻게해야할지 모르겠다. 메신저에 대한 MSDN 기사를 다시 읽었지 만 그 질문에 어떻게 도움이되는지는 알지 못합니다. 나는 다음의 최신 코드를 포함시켰다. 댓글 섹션을 참조하십시오. 샘플에서

public class ChildViewModel 
{ 
    public ChildViewModel(IChildService service) 
     { 
      this.ServiceProxy = service; 
      this.MessengerInstance.Register<ParentViewModel.ParentToChildMessage>(this, this.OnParentToChildMessage); 
      this.ChildCollection = new ObservableCollection<Child>(); 
      GetChildInfo(this.CurrentParent); 
     } 
} 
+0

부모보기에 하위보기의 인스턴스를 만듭니다. xaml 되보기. 나는 부모에게 자식 컨트롤의 인스턴스를 추가하여 동시에 인스턴스가 생성되도록 제안했습니다. – kidshaw

답변

3

, 그것의 ViewModel이보기에 이야기하고 제안 :

public class ParentViewModel 
{ 

public ICommand ShowChildCommand 
    { 
     get { return new RelayCommand(OnLoadChildCommand); } 
    } 

private void OnLoadChildCommand() 
    { 
    Messenger.Default.Send(new ParentToChildMessage { Parent = this.CurrentParent }); 
    // ****** this is where I instantiated the child view 
    // I am sure this is wrong... 
    var view = new ChildView().Show(); 
    } 

public class ParentToChildMessage : MessageBase 
    { 
     public Parent Parent { get; set; } 
    } 
... 
} 

그리고 ChildViewModel는 것 같습니다. MVVM 패턴으로 이미 점프 한 경우에는 피해야합니다.

MVVM에서 메시지 프레임 워크를 사용하여이 작업을 수행합니다. 상위 뷰와 하위 뷰를이 방식으로 분리하고 둘을 결합하지 않고 데이터를 전달할 수 있습니다. 하위 뷰 모델에서 하위 뷰의 가시성을 제어하고 메시지 처리기에서 하위 뷰를 토글 할 수 있습니다.

이 msdn 기사에서는 개념을 소개합니다. http://msdn.microsoft.com/en-us/magazine/dn745866.aspx. 편집에 근거

...

먼저 기본 단계는 부모로부터 자식에게 데이터를 전달하는 메시지 클래스를 만드는 것입니다.

public class ParentToChildMessage : MessageBase 
{ 
    /// Include any properties you want to send 
} 

당신이 전달하는 데이터가없는 경우, 당신은 자신에게 코드의 비트를 저장하는 부울을 통과 MVVM 빛의 GenericMessage <> 객체를 사용할 수 있습니다. 그러나 메시지는 유형별로 등록되므로 일반적인 등록 방법을 사용하면 더 많은 검사를 수행해야합니다.

부모보기 모델에는 ShowChildCommand 명령이 있습니다.이 명령을 사용하여 메시지를 보내는 지점으로 사용할 수 있습니다.

public class ParentViewModel : ViewModelBase 
{ 
    public ParentViewModel() 
    { 

    } 

    public ICommand ShowChildCommand 
    { 
     get 
     { 
      return new RelayCommand(()=>this.MessengerInstance.Send<ParentToChildMessage>(new ParentToChildMessage())); 
     } 
    } 
} 

부모보기 모델 용입니다. 다음으로 자식 뷰 모델에 메시지 수신기를 등록합니다.

public class ChildViewModel : ViewModelBase 
{ 
    public ChildViewModel() 
    { 
     this.MessengerInstance.Register<ParentToChildMessage>(this, this.OnParentToChildMessage); 
    } 

    private void OnParentToChildMessage(ParentToChildMessage obj) 
    { 
     // Inspect obj to decide what to do - let's just set as visible 
     this.IsVisible = true; 
    } 

    public bool IsVisible 
    { 
     get 
     { 
      return _IsVisible; 
     } 
     set 
     { 
      if (value != _IsVisible) 
      { 
       _IsVisible = value; 
       RaisePropertyChanged(); 
      } 
     } 
    } 
    private bool _IsVisible; 
} 

여기 생성자에서 강력한 유형의 메시지를 등록합니다. generic을 사용했다면 OnParentToChildMessage 본문과이 유형의 다른 가능한 메시지를 구별해야합니다. 예를 들어 예쁜 코드가 아니어야합니다. 특히 시간이 지남에 따라 여러 메시지 상호 작용을 구축 할 가능성이 높습니다.

하위보기 모델은 간단한 bool IsVisible 속성을 업데이트합니다.이 기능을 사용하려면 부모보기에 하위보기 인스턴스가 있어야합니다. 그렇게하면 자녀보기가 생성되고 자녀보기 모델의 인스턴스가 생성됩니다.

이 정보가 도움이되기를 바랍니다.

+0

# kidshaw : 현재 MVVMLight 툴킷의 해당 부분을 활용하지 않기 때문에 메신저 개념을 살펴 보겠습니다. 내 코드의 어떤 부분을 보시겠습니까? – user118190

+0

나는 원래의 게시물을 편집하여 일부 도움을 얻은 코드 스 니펫을 추가했습니다. – user118190

+0

@ user118190, 내가 준 대답은 약간의 간략한 것이므로 더 많은 코드를 사용하여 예제를 줄 수있었습니다. 자신을 조사하는 것이 행복하다면 언제든지 기쁘게 생각하십시오. 사실 ViewModelLocator를 사용하면 당신이 제공 한 여분의 코드에서 꽤 유능하다는 것을 알 수 있습니다. 오늘 제 답변을 약간 나중에 업데이트 할 것입니다. – kidshaw