2009-10-12 4 views
1

나는 목록 상자가 List<T>에 바인딩되어 있습니다. 이것은 훌륭하게 작동합니다.리스트/세부 정보 서로 다른 Windows를 동일한 컬렉션에 동기화하고 데이터 바인딩 할 수 있습니까?

사용자가 목록 상자 항목을 두 번 클릭하고 해당 레코드에 대한 "세부 정보"보기를 표시 할 새 창을 열게하고 싶습니다. 이 새 창을 원래 창에있는 목록 상자와 동일한 컬렉션으로 데이터 바인딩해야합니다. 그 창에는 업데이트 된 데이터에 대한 webserivce를 폴링하는 타이머가 있기 때문에 기본 목록이 업데이트 될 때 하위 (세부 정보 창)도 업데이트하고 싶습니다.

쉽게 할 수 있습니까? 좋은 예가 될 수 있지만 도움이 될 것입니다!

답변

7

데이터를 직접 공유 할 수 있지만 (즉, SelectedItem 참조를 자식 창으로 전달), 여러 창에서 동작 및 상태를 관리하는 데 도움이되지 않습니다. 문제가 적은 읽기 전용보기이지만 데이터가 변경되는 경우 매우 빠르게 문제가 발생합니다.

이것은 Model-View-를 사용하는 이점의 좋은 예입니다. 무늬. MVVM은 일반적으로 WPF에서 선호되는 패턴입니다. 왜냐하면 WPF는 완전한 분리 분리를 위해 설계 되었기 때문입니다. 그러나 이와 같은 경우에는 고유 한 UI 요소간에 동작과 상태를 조정해야하기 때문에 MVC (Model-View-Controller)에 더 가깝게 할 수 있습니다.

하이브리드 방식을 권장합니다. 약어를 더 길고 어색하게 만들기 위해 "MVVMC"라고 부르 자고합니다. ViewModel은 UI에 완벽하지 않으며 데이터 및 데이터 관련 상태/동작 (대개 CRUD 유형의 것들) 만 노출합니다. 그런 다음 ViewModel을 소비 및 노출 (위임 또는 컴포지션 중 하나)하지만 캡슐화하는 UI 디자인에 특정한 컨트롤러를 구현합니다. 하여 멀티 윈도우 표시 동작의 모든 - 등

public class MyViewModel : INotifyPropertyChanged, INotifyCollectionChanged 
{ 
    public MyViewModel(DataModel dataModel) { ... } 
} 

public class MyController 
{ 
    public MyController(MainWindow mainWindow, ViewModel viewModel) { ... } 
    public ViewModel { get { return _viewModel; } } 
    public ICommand DisplayChild { ... } 
} 

을 가까운 요청을 전파, 그래서 당신은 정말 MVVM을 복용하고있어, 다음 반전 제어 항목 당 하나 개의 창을 시행 가지 컨트롤러가 수 멀티 윈도우 UI를 관리합니다. 따라서 여기 컨트롤러는 쉬운 바인딩을 위해 DataContext로서 ViewModel을 윈도우 (메인 포함)에 삽입합니다. 그것은 또한 메인 윈도우의 이벤트에 바인딩하고, 자식 윈도우를 시작하고, 적절하게 관리하기 위해 자식 윈도우 이벤트에 바인딩합니다 (예 : 자식 레코드 당 하나의 윈도우, 메인 닫을 때 닫는 자식 등).

여기에서 한 걸음 더 나아가 Windows 대신 인터페이스에 대해 컨트롤러를 구현할 것입니다. 이렇게하면 리팩토링에 어느 정도 융통성이 생기지 만 더 중요한 것은 컨트롤러를 mock에 대해 단위 테스트 할 수 있다는 것입니다.

public interface IControllerChild 
{ 
    public void Show(); 
    public bool Activate(); 
    public void Close(); 
    // add other behaviors here 
} 

public class DetailWindow : Window, IControllerChild 
{ 
    // implement other behaviors here 
} 

public class MockControllerChild : IControllerChild 
{ 
    public void Show() { IsShowing = true; ActionLog.Add(MockControllerAction.Show); } 
    public void Activate() { IsShowing = false; ActionLog.Add(MockControllerAction.Activate); } 
    public void Close() { IsShowing = false; ActionLog.Add(MockControllerAction.Close); } 
    public bool IsShowing { get; private set; } 
    public IList<MockControllerAction> ActionLog { get; private set; } 
    // mock and record other behaviors here 
} 

public enum MockControllerAction 
{ 
    Show, 
    Activate, 
    Close, 
    // Add other behaviors here 
}; 
+0

이와 같은 자세한 답변을 제공해 주셔서 감사합니다. 나는 이것에 대해 살펴보고 조금 더 소화해야 할 것이다. 그것은 내가 원하는 것에 대해 과잉 느낌처럼 느껴진다. 그러나 나는 그것이 최선의 방법이라는 것을 깨닫는다. – Nate

+0

그러나 가장 좋은 대답으로 받아 들일 수는 있지만, 필자의 경우에는 인스턴스에 대한 참조를 앞뒤로 전달할 수 있었기 때문에 내 요구에 적합했습니다. – Nate