2012-09-17 4 views
0

이상한 동작이 발생합니다. MVVM 패턴을 사용하고 있는데, AlarmView라는 이름의 Observable 컬렉션에 AlarmCollection이라는 그리드 컨트롤에 대한 바인딩이있다. AlarmModelView 클래스의 인스턴스를 여러 개 만들고 AlarmCollection에 항목을 추가하면 모든 인스턴스가 변경 사항을 표시합니다.MVVM 하위 인스턴스의 ObservableCollection 동작

ObservableColelction AlarmCollection을 변경하면 모눈 컨트롤의 모든 바인딩 된 ItemSources에 영향을줍니다.

비슷한 게시물의 디스패처 스레드를 아무 쓸모없이 잠그려고했습니다.

ViewModel의 각 인스턴스 내에서이 Observable 컬렉션의 변경 사항을 유지할 수 있습니까? 그래서 각 수정은 UI 스레드의 다른 콜렉션에는 영향을 미치지 않습니다.

도움을 주시면 감사하겠습니다.

[편집 아래] 내가 다시 부모 MV에 탭을 추가하는 아이 MV의 새로운 인스턴스를 생성하여 렌더링 무엇에/드릴을 확대 이상한 시나리오 필요가있다
. Child Views는 모두 동일한 Collection 이름에 바인딩되며 모두 은 WCF 비동기 호출에 의해 업데이트됩니다. 확대/축소 수준이 얼마나 깊은지를 기준으로 X 번호가 여러 개인 인스턴스가 필요하므로 ModelView 객체가 하나 필요합니다.

어떻게 내가 CollectionChanged 이벤트를 사용하거나 ModelView 자신의 CollectionView를 만들 수 있습니까? 모든 뷰가 동일한 기본 컬렉션에 바인딩 된 것처럼 당신의 묘사에서

private MainViewModel _parentViewModel; 
    public MainViewModel ParentViewModel 
    { 
     get { return _parentViewModel; } 
     set 
     { 
      if (ParentViewModel == value) { return; } 

      SetPropertyValue(ref _parentCircuitViewModel, value, "ParentViewModel"); 
     } 
    } 



    private ObservableCollection<DetailEntity> _alarmCollection; 
    public ObservableCollection<DetailEntity> AlarmCollection 
    { 
     get 
     { 
      if (_alarmCollection == null) 
       _alarmCollection = new ObservableCollection<DetailEntity>(); 

      return _alarmCollection; 
     } 
     private set { _alarmCollection = value; } 
    } 

    ServiceNode _selectedNode; 

    public ServiceNode SelectedNode 
    { 
     get { return _selectedNode; } 
     set 
     { 
       SetPropertyValue(ref _selectedNode, value, "SelectedNode"); 

       // render selected child node service path 
       RenderSubPath(_selectedNode); 

       // reset storage value 
       _selectedCircuitNode = null; 

     } 
    } 

    // Constructor 
    public RenderViewModel(string servicePath CircuitMainViewModel parentViewModel) 
    { 
     ServicePath = servicePath, 
     ParentCircuitViewModel = parentViewModel; 


     // event to handler for completed async calls 
     Client.GetAlarmsByNodeListCompleted += new EventHandler<GetAlarmsByNodeListCompletedEventArgs>(Client_GetAlarmsByNodeListCompleted); 

    } 

    void RenderSubPath(ServiceNode childNode) 
    { 
     if (childNode == null) 
      return; 
      // create a new child instance and add to parent VM tab 
       _parentViewModel.AddServiceRenderTab(new ViewModel.Workspaces.RenderViewModel(childNode.elementPath _parentViewModel); 
    } 

     // wcf async webservice call to add alarm to ObservableCollection 
     // ** This is updating all Collections in all Views. 
     void Client_GetAlarmsByNodeListCompleted(object sender, AlarmServiceReference.GetAlarmsByNodeListCompletedEventArgs e) 
     { 
      try 
      { 
       if (e.Result == null) 
        return; 

       // add to parent Netcool alarm collection 
       foreach (DetailEntity alarm in nodeAlarms) 
       { 
        _alarmCollection.Add(alarm); 
       } 

      } 
    } 
+0

모든 뷰가 동일한 'ObservableCollection'에 바인딩되어 있습니까? –

+0

모든보기가 동일한 콜렉션에 바인딩되어있는 것처럼 보입니다.이 결과는 정상입니다! 당신은 각보기마다 하나씩 다른 목록을 만들어야합니다. – Damascus

+0

응답 주셔서 감사합니다. 일부 코드를 재 게시했습니다. – mflair2000

답변

1

, 그것은 소리. 바인딩하는 컬렉션의 경우 WPF는 실제로 컬렉션에 래핑 된 컬렉션 뷰 (ICollectionView)에 바인딩됩니다. 명시 적으로 자신의 콜렉션 뷰를 작성하지 않으면, 디폴트의 콜렉션 뷰가 사용됩니다. 동일한 콜렉션에 바인딩하면 동일한 콜렉션 뷰가 사용됩니다.

코드를 보지 않고 말하기는 어렵지 만 기본 뷰 모델 (따라서 컬렉션)의 별도 인스턴스를 사용하거나 별도의 컬렉션 뷰를 명시 적으로 만들고이를 바인딩하려는 경우가 많습니다 대신.

+0

응답 해 주셔서 감사합니다. – mflair2000

+0

이상한 scenerio입니다, 나는 하위 MV의 새 인스턴스를 생성하여 렌더링되는 것을 렌더링 및 드릴링해야합니다.이 MV는 부모 MV에 탭을 추가합니다. 하위 뷰는 모두 동일한 컬렉션 이름에 바인딩되며 모두 업데이트됩니다. 나는 줌 레벨이 얼마나 깊은지를 기반으로 X number multiple instances를 필요로하므로 인스턴스가 1 개 필요합니다. 인스턴스에 포함될 CollectionView를 어떻게 만들 수 있습니까? (나는 원래의 대답으로 코드를 업데이트 할 것이다) – mflair2000

관련 문제