2009-11-11 1 views
2

범위크기에 따라 컨트롤을 정렬하는 방법은 무엇입니까? 내 응용 프로그램이 일부 복잡한 컨트롤 라인을 마련하고 페이지로 그 라인을 분할하도록 노력하고

(패널에서 상속 제외). 다음과 같은 것 : alt text http://apreleva.com/vm/controls-in-pages.png

워드 프로세서와 마찬가지로, 단어 대신 복잡한 컨트롤이 있습니다. 페이지로 분할해야한다는 요구 사항이 중요합니다.

Panel에서 상속하고 MeasureOverride/ArrangeOverride를 구현하는 명백한 해결책은 할 수 없습니다. 왜냐하면 저는 페이지를 별도의 프레임 워크 요소로 사용하고 싶기 때문입니다. 이렇게하면 멋진 것들을 할 수 있습니다. 그 (것)들과, 그 (것)들을 주변에 끄는 같이, 자전, 등등. 나는 최후의 수단으로이 해결책 (위원회를 상속한다)을 생각하고있다, 그러나 나는 더 나은 방법이어야한다 확실하다.

채택 전략은

이것은 내가 그 컨트롤의 크기를 알고 있으면, 상대적으로 간단한 일처럼 보인다. 저는 페이지에 수직 방향의 스택 패널을 사용하고 라인에는 수평 방향의 스택 패널을 사용합니다. 나는 줄의 너비를 초과 할 때까지 줄을 하나씩 꾸며서 다음 줄의 스택 패널을 만들고 계속한다. 다음 줄이 현재 페이지에 맞지 않으면 다음 페이지를 만들고 프로세스가 진행됩니다.

나는 한 번에 수백 개의 컨트롤을 기대하기 때문에이 접근 방식을 사용해야한다고 생각했습니다.

문제

문제는 내가 윈폼에서 기대할 수있는 매우 하나입니다 : 나는 그 컨트롤의 크기를 몰라! 컨트롤의 폭과 높이가 명시 적으로 설정되어 있지 않은 경우, 생성 직후에 DesiredSize가 0이됩니다.

이 문제는 .Measure (Size.Empty)를 호출하여 해결할 수 있습니다. 그 후, DesiredSize가 (다소) 올바르게 계산됩니다.

"다소"라고 말합니다. 불행히도 아직 완전히 정확하지 않기 때문입니다. 내가 발견 한 가장 최근의 문제는 상대 소스에 바인딩하는 것입니다. 다음 XAML을 고려해보십시오.

<ItemsControl x:Class="MyClass" xmlns=...> 
    <ItemsControl.ItemTemplate> 
     <Ellipse Width={DataBinding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MyClass}}, Path=EllipseWidth} /> 
    </ItemsContro.ItemTemplate> 
</ItemsControl> 

여기서 "EllipseWidth"는 내 사용자 지정 ItemsControl 하위 클래스 인 MyClass의 속성입니다.

Measure() 호출로 ItemsControl이 항목을 만들지 만 바인딩이 해결되지 않습니다. 구체적으로

52 : Created BindingExpression (hash=15030582) for Binding (hash=15006601) 
54 : Path: 'EllipseWidth' 
56 : BindingExpression (hash=15030582): Default mode resolved to OneWay 
57 : BindingExpression (hash=15030582): Default update trigger resolved to PropertyChanged 
58 : BindingExpression (hash=15030582): Attach to Ellipse.Width (hash=12274123) 
62 : BindingExpression (hash=15030582): RelativeSource (FindAncestor) requires tree context 
61 : BindingExpression (hash=15030582): Resolve source deferred 

마지막 두 줄을 참고 : 추적을 확인하십시오. "트리 컨텍스트"란 무엇이며 어떻게 제공합니까? Measure()를 호출하기 전에 "라이브"패널에 컨트롤을 추가하려했지만 많은 도움이되지 않았습니다.

필자는 추적에 따라 소스가 결국 해결되지만 너무 늦었습니다. 지금 컨트롤 크기를 알아야합니다.나는이 바인딩 문제를 해결하더라도 문제

을 일반화

, 나는 어떤 사람이 없을 것이라고 확신 할 수 없다. 궁극적 인 질문은 다음과 같습니다. 컨트롤의 초기화가 완료되면 알 수있는 "깨끗한"방법이 필요합니다. 해당 컨트롤의 크기를 찾으려면

또는 다른 옵션) 어쩌면 내가 잘못된 접근법을 취하고 있으며, 내가하려고하는 일을하는 또 다른, 더 깨끗한 방법이 있을까요?

답변

0

컨트롤 구성을 사용하여 원하는 것을 달성 할 수 없을 것이라고 생각합니다. 나는 당신이 반드시 Measure/Arrange에 참여하고 자신의 알고리즘을 제공 할 필요가 있다고 생각합니다. 이 작업을 수행하기 위해 Panel을 상속 할 필요는 없지만 일반적으로 가장 적합합니다. 페이지의 경우, 사용자 정의 패널은 각 논리적 그룹에 대해 뒷면을 방출 할 수 있습니다. 마침내 커스텀 패널은 다양한 크기를 지원할 수 있도록 논리적 그룹화를 구성하는 차원으로 구성 될 수 있습니다 (Letter 대 A4 등을 지원한다고 상상해보십시오).

그래서 결국 난 당신이와 끝까지해야한다고 생각 무엇 :

  1. 사용자 정의 가지를 배치하고 다양한 속성을 통해 구성 크기에 따라 논리적 그룹을 결정 지원 Panel 구현입니다.
  2. 논리적 그룹을 생성 할 때 논리 그룹의 "배경"으로 렌더링하여 효과적으로 "페이지"를 만드는 데 사용하는 ItemGroupTemplate과 같은 속성을 표시합니다. ItemsControl
  3. 에 실제 항목 데이터 바인딩
  4. 마지막으로, 당신은 아마 당신의 패널에서 가상화 알고리즘을 사용하려는거야 명심 ItemControl::ItemsPanel

로 정의 Panel을 설정하면 경우 그 많은 아이템을 배치 할 것입니다. 즉, VirtualizingPanel에서 상속해야합니다. 사용자 지정 VirtualizingPanel을 만드는 방법에 대한 자세한 내용은 check out Dan Crevier's awesome series on the subject을 참조하십시오.

+0

글쎄, 이것이 바로 내가 백업으로 유지하고 있던 "마지막 수단"해결책입니다. 아무도 다른 대답을주지 않으면 확실하게이 길로 갈 것입니다.하지만이 방법을 사용하면 페이지를 별도의 프레임 워크 요소로 취급 할 수있는 능력이 느슨합니다. 회전, 회전, 접기 등등 ... –

관련 문제