2013-08-26 4 views
4

다른 스레드를 생성하여 UI 스레드에 넣으면 Visual Tree에 추가 할 수 없다는 것을 알고 있습니다. 다른 스레드가 해당 스레드를 소유하고 있기 때문에 해당 개체에 액세스 할 수 없다는 예외가 발생합니다.WPF에서 무거운 사용자 컨트롤 만들기

내 현재 시나리오는 200 (FrameworkContentElement) 컨트롤을 DockWindow에 추가하는 것과 같이 많이 사용하고 있습니다. 이 UI를 동결하지 않고 UI 스레드에로드하려고 할 수 있습니까? 다른 스레드에서 작업하는 동안 대화 상자를 표시하는 동안 UI 스레드를 사용하기 때문에 진행 대화 상자를 표시 할 수 없습니다. 처리해야하는 것이 데이터이고 UI에 배치해야하지만 이번에는 이들을 작성해야합니다. UI 컨트롤.

UI 컨트롤을 만들고이를 MemoryStream에 직렬화하여 UI 스레드에로드하는 방법을 생각해보십시오. 한 가지 문제는 컨트롤에 DataContext를 다시 첨부해야한다는 것입니다. 그 순간에 다른 스레드에 위임 할 수 있습니다. 문제는 여전히 이것입니다 실현 가능 할 수 있습니까?

ApartmentState를 STA로 만들기 위해 Task와 Thread 객체를 섞어 보았지만 여전히 운이 없었습니다.

public static Task<T> StartSTATask<T>(Func<T> func) 
    { 
     var tcs = new TaskCompletionSource<T>(); 
     Thread thread = new Thread(() => 
     { 
      try 
      { 
       tcs.SetResult(func()); 
      } 
      catch (Exception e) 
      { 
       tcs.SetException(e); 
      } 
     }); 
     thread.SetApartmentState(ApartmentState.STA); 
     thread.Start(); 
     return tcs.Task; 
    } 

편집 :이 컨트롤이 다시 도움이되지 않습니다이 시나리오에서 컨트롤을 가상화, FrameworkContentElement 있습니다. 이것은 런타임에 컨트롤을 만드는 FlowDocument 컨트롤과 함께 사용됩니다. 말해, 실행, 테이블, 단락 등. 따라서 ListBox, TreeViews 등은이 시나리오에 적용 할 수 없습니다.

+0

[가상화 컨트롤] (http://msdn.microsoft.com/en-us/library/cc716879.aspx)을 확인 했습니까? – Shoe

+0

예 이러한 컨트롤은 불행히도 FrameworkContentElement이고 FrameworkElements가 아니라는 것을 알고 있습니다. RichTextBox/FlowDocumentScrollViewer 컨트롤로로드하고 있습니다. –

답변

2

컨트롤이 WPF를 정상적인 컴퓨터에서 렌더링하는 데 큰 문제가되지 않도록하려면 개의 프리미티브이 필요합니다.

데이터를로드하고 구문 분석하는 동안 진행률 막대를 표시 할 수 있습니다. 그런 다음 필요에 따라 데이터 위에 UI 스레드 프로세스 루프가 있고 UI 스레드를 호출하여 컨트롤을 인스턴스화함으로써 UI 요소 작성을 제한 할 수 있습니다. 화면을 렌더링 할 수 있도록 작은 수면에 의한 인스턴스화를 분리 할 수도 있지만 매우 무거운 UI에 대해서만 사용하십시오 ...

... 그 말은 - UI가 너무 무거 우면 틀리게 설계 할 것입니다. . 질문은 이 아니어야합니다. "UI가 드래그까지 느려지 기 전에 몇 개의 UI 요소를 넣을 수 있습니까?" 하지만 "가장 작은 숫자의 활성 작업을 수행 할 수있는 요소는 무엇입니까?"

"활성"이라는 단어는 실제 항목이 가상화되는 listviews에서 사용하는 접근법을 말하며, 필요에 따라 작성되고 표시되지 않는 경우 삭제됩니다. 따라서 DockPanel 대신 UI에서 허용되는 경우 ListView와 같은 가상화 컨테이너를 사용하는 것이 좋습니다.

특정 UI 요소의 예를 제공 할 수 있다면 더 자세히 설명 할 수 있습니다.

+0

방금 ​​내 질문을 업데이트했는데, 그것은 내가 생각했던 것입니다. 불행히도 모든 런타임 컨트롤을 생성하는 데는 잠시 시간이 걸립니다.FlowDocument로 렌더링되는 (Xaml) 템플릿이 있으며 우리가 가지고있는 모든 자리 표시 자 컨트롤을 적절한 컨트롤로 대체합니다. 이런 종류의 매핑은 런타임을 대체합니다. –

+0

나는 docx-> FlowDocument 파서를 작성했으며 동일한 문제 - 끔찍한 FlowDocument 성능을 경험했습니다! 가능한 한 평면 구조에 집착하십시오 (테이블을 잡기 위해 FlowDocument에 캔바스를 넣지 마십시오 :)). FlowDocument를 숨기고, 내용을로드 한 다음, 보이게하고, 윤곽선을 가짜로 만들어 사용자에게 물건이 들어오는 것을 알립니다. –

+0

FlowDocument/anything에 캔버스가 없습니다. 난 그냥 적절한 컨트롤을 사용하여 문서를 만들 때 그것은 우리가 그 컨트롤 런타임을 대체해야하고 시간이 걸립니다. –

관련 문제