2016-12-25 2 views
-2

За последние несколько дней я пытался обернуть вокруг головы следующей компоновки TextBlocks:WPF - комплекс TextBlock макет

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

Все TextBlocks имеет динамическую ширину. Они имеют фиксированную высоту и находятся в контейнере фиксированного размера. Они должны отвечать следующим требованиям:

  • 2 имеет максимальный приоритет - он всегда должен быть на полной длине.
  • 3 может заполнить оставшееся пространство, оставшееся после калибровки 2.

При игнорировании TextBlock 1, эти два требования могут быть выполнены путем ввода двух других TextBlocks в сетке, с колоннами, установленными на «авто» и " * "соответственно.

Существует третье требование, хотя:

  • 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 (новый Rect (organizSize.Width - sizeLabel2.Width, 0, sizeLabel2.Width, sizeLabel2. Высота)); InternalChildren [0] .Arrange (новый Rect (0, 0, organizSize.Width - sizeLabel2.Width, sizeLabel0.Height)); '. Если вы измените свой ответ, я приму его. – Mastah

+0

Я рад, что у вас есть идея и вы можете адаптировать логику к вашим потребностям. Я обновил свой ответ. – gomi42