2016-12-25 15 views
-2

다음 TextBlocks의WPF - 복잡한 TextBlock의 레이아웃 내가 TextBlocks 다음과 같은 레이아웃 주위에 내 머리를 정리하려고했는데 지난 몇 일 동안

-------------------- ----------- 
|   1  | |   | 
-------------------- | 3 | 
|  2  | |   | 
----------------- ----------- 

모든 동적 폭을 가지고있다. 높이가 고정되어 있으며 고정 크기의 컨테이너에 있습니다. 다음 요구 사항을 충족해야합니다.

  • 2는 항상 전체 길이 여야합니다.
  • 3 세트 열이, TextBlock의 1,이 두 가지 요구 사항이 그리드에 다른 두 TextBlocks을 넣어 성취 될 수 무시하는 경우 2.

크기를 조정 한 후 남은 공간을 채울 수있는 "자동"과 "에 * "로 표시됩니다.

하지만 세 번째 요구 사항이 있습니다 :

  • 1가 할 수있는 모든 공간을 가정,하지만 3

예를 제한하지 않고 :

블록 3 (블록 2

긴 내용 콘텐츠는 전체 길이이며 블록 3 콘텐츠는 다듬어집니다.) :

----------------- ------------- 
|  1  | |   | 
----------------- |  3  | 
|  2  | |   | 
----------------- ------------- 

블록 3의 짧은 내용 (블록 2 및 3의 내용 모두 전체 길이입니다. 블록 1은 나머지 공간을 채 웁니다.) :

--------------------- --------- 
|   1   | |  | 
--------------------- | 3 | 
|  2  |  |  | 
-----------------  --------- 

WPF에서이 레이아웃을 달성 할 수있는 방법이 있습니까? 방법?

답변

0

순수 XAML에서는 가능하지 않다고 생각합니다. 요구 사항을 달성하는 한 가지 방법은 모든 마법을 수행하는 자체 패널을 구현하는 것입니다.

public class SpecialPanel : Panel 
{ 
    protected override Size MeasureOverride (Size constraint) 
    { 
     foreach (UIElement child in Children) 
     { 
      child.Measure (constraint); 
     } 

     return constraint; 
    } 

    protected override Size ArrangeOverride (Size arrangeSize) 
    { 
     if (VisualChildrenCount != 3) 
     { 
      return (arrangeSize); 
     } 

     Size sizeLabel0 = InternalChildren[0].DesiredSize; 
     Size sizeLabel1 = InternalChildren[1].DesiredSize; 
     Size sizeLabel2 = InternalChildren[2].DesiredSize; 

     InternalChildren[1].Arrange (new Rect (0, sizeLabel0.Height, sizeLabel1.Width, sizeLabel1.Height)); 
     var maxRemainingWidthFor2 = arrangeSize.Width - sizeLabel1.Width; 

     if (maxRemainingWidthFor2 <= 0) 
     { 
      InternalChildren[0].Arrange (new Rect (0, 0, sizeLabel0.Width, sizeLabel0.Height)); 
     } 
     else 
     { 
      if (maxRemainingWidthFor2 < sizeLabel2.Width) 
      { 
       InternalChildren[2].Arrange (new Rect (arrangeSize.Width - maxRemainingWidthFor2, 0, maxRemainingWidthFor2, sizeLabel2.Height)); 
       InternalChildren[0].Arrange (new Rect (0, 0, Math.Min (sizeLabel0.Width, sizeLabel1.Width), sizeLabel0.Height)); 
      } 
      else 
      { 
       var max0 = arrangeSize.Width - maxRemainingWidthFor2; 
       var width0 = Math.Min (sizeLabel0.Width, max0); 

       InternalChildren[2].Arrange (new Rect (arrangeSize.Width - sizeLabel2.Width, 0, sizeLabel2.Width, sizeLabel2.Height)); 
       InternalChildren[0].Arrange (new Rect (0, 0, arrangeSize.Width - sizeLabel2.Width, sizeLabel0.Height));. 
      } 
     } 

     return arrangeSize; 
    } 
} 

사용법 : 대답에 대한

<local:SpecialPanel> 
     <Label 
      x:Name="Label1" 
      VerticalContentAlignment="Center" 
      Content="TextBlock00000000000000" /> 
     <Label 
      x:Name="Label2" 
      VerticalContentAlignment="Center" 
      Content="TextBloc111111111111" /> 
     <Label 
      x:Name="Label3" 
      HorizontalContentAlignment="Center" 
      VerticalContentAlignment="Center" 
      Content="Label333333" /> 
    </local:SpecialPanel> 
+0

덕분에 여기 하나의 구현입니다. 그러나 두 번째 예제에서는 예상대로 작동하지 않습니다. 코드를 수정하여 마지막 'else' 분기를 다음과 같이 변경해야합니다 : InternalChildren [2] .Arrange (arrangeSize.Width - sizeLabel2.Width, 0, sizeLabel2.Width, sizeLabel2. 신장)); InternalChildren [0] .Arrange (new Rect (0, 0, arrangeSize.Width - sizeLabel2.Width, sizeLabel0.Height));'. 답변을 수정하면 동의 할 것입니다. – Mastah

+0

아이디어를 얻었고 필요에 따라 논리를 적용 할 수있어서 기쁩니다. 나는 나의 대답을 업데이트했다. – gomi42