2012-10-19 2 views
3

빌드 할 때 엄청난 시간이 걸리는 큰 3 계층의 개체 목록을 채우는 데 필요한 TreeView 컨트롤이 있습니다. 백그라운드 스레드에서 데이터를 로딩 한 다음 GUI 스레드로 GUI 업데이트를 보내고 있지만 너무 많은 업데이트가 있습니다. 노드를 추가 할 때마다이를 보내야합니다. ExpandSubTree() 메서드를 호출하여 모든 하위 노드를 확장 한 다음 더 많은 확장 이벤트를 발생 시키면 충돌이 발생합니다.백그라운드 스레드에서 TreeView 컨트롤을 빌드하는 방법이 있습니까?

컨트롤을 빌드 할 수있는 방법이 있습니까? 백그라운드 스레드에서 어떻게 든 열고 닫은 상태를 유지 한 다음 완료되면 마샬링합니다.

+0

왜 Windows의 Invoke 메서드를 사용하지 마십시오 컨트롤 클래스 –

답변

0

각 트리보기 항목에는 하위 트리가 있습니다. 각 트리보기 항목의 하위 항목을 ObservableCollection에 바인딩하면 BackGroundWorker 또는 다른 스레드에서 항목을 추가 할 수 있습니다. 후속 컬렉션을 사용하여 트리보기 항목 하위를 바인딩하는 경우 백그라운드에서 하위보기로 자식을 추가 할 수 있습니다.

Simplifying the WPF TreeView by Using the ViewModel Pattern

Custom TreeView Layout in WPF

희망이 유용 할 것이다 : 또한

public class ThreadSafeObservableCollection<T> : ObservableCollection<T> 
{ 
    private SynchronizationContext SynchronizationContext; 

    public ThreadSafeObservableCollection() 
    { 
     SynchronizationContext = SynchronizationContext.Current; 

     // current synchronization context will be null if we're not in UI Thread 
     if (SynchronizationContext == null) 
      throw new InvalidOperationException("This collection must be instantiated from UI Thread, if not, you have to pass SynchronizationContext to con        structor."); 
    } 

    public ThreadSafeObservableCollection(SynchronizationContext synchronizationContext) 
    { 
     if (synchronizationContext == null) 
      throw new ArgumentNullException("synchronizationContext"); 

     this.SynchronizationContext = synchronizationContext; 
    } 

    protected override void ClearItems() 
    { 
     this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.ClearItems()), null); 
    } 

    protected override void InsertItem(int index, T item) 
    { 
     this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.InsertItem(index, item)), null); 
    } 

    protected override void RemoveItem(int index) 
    { 
     this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.RemoveItem(index)), null); 
    } 

    protected override void SetItem(int index, T item) 
    { 
     this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.SetItem(index, item)), null); 
    } 

    protected override void MoveItem(int oldIndex, int newIndex) 
    { 
     this.SynchronizationContext.Send(new SendOrPostCallback((param) => base.MoveItem(oldIndex, newIndex)), null); 
    } 
} 

나는이 기사가 당신에게 유용해야한다고 생각 : 그것은보기에 항목을 추가 동기화 컨텍스트를 사용 당신을 위해 ...

+0

고마워, 필자는 실제로 ap MVVM과 함께 이제는 좋은 디자인 방식 인 것처럼 보이게됩니다. 새로운 패턴을 시도 할 수있는 좋은 기회입니다 :) 그 링크는 매우 도움이되었습니다. 감사합니다. – NZJames

+0

임 MVVM은 훌륭합니다! 또한이 답변이 정말로 효과가 있다면 받아 들일 수 있기를 바랍니다. 감사 –

0

한 번에 전체 트리를 만들고 있습니까? 생성 된 각 항목에 대한 호출을 실행하고 있습니까?

필요에 따라 트리를로드하는 방법에 대해 생각해 보겠습니다. 어쩌면 사용자가 노드를 확장하기 위해 이동하면 해당 이벤트를 처리하고 데이터를 가져올 수 있습니다. 또한 호출 당 항목 그룹로드를 고려할 것입니다.

관련 문제