2014-12-22 4 views
1

Трудно описать мою проблему в нескольких словах!
Это то, чего я пытаюсь достичь.Правильное выравнивание объектов внутри обертки при изменении объектов

enter image description here

Объект # 1 обычно заполняет ширину своего родителя.
Он может быть сведен к минимуму до части его прежней ширины, и когда это произойдет, это выровненное по правому краю в его родительском. Объект # 2 автоматически помедленнее, чтобы заполнить пробел и с левой стороны ..

Я пробовал различные стековые панели, обертки и док-панели, но не могу понять проблему макета.

Есть ли способ разрешить это поведение без большого количества уродливых математик в коде?

+0

изменить размер 1, и изменить порядок двух внутри 'WrapPanel'. Разумеется, нужно сделать математику при вычислении нового размера. – kennyzx

+0

@kennyzx, вы * можете * неправильно понять проблему ... Я не думаю, что 'WrapPanel' заменит порядок двух элементов, когда первый будет сведен к минимуму ... не так ли? – Sheridan

+0

# 1 должны быть выровнены по правому краю, а # 2 - влево. Это моя главная проблема. – DefenestrationDay

ответ

0

Ну, я что-то придумал. Возможно, это не самый элегантный в мире, но он работает для моего прецедента.

public class CollapsingPanel : Panel 
{ 
    /// <summary> 
    /// parents are supposed to ask their children what their desired size is, given an available size 
    /// </summary> 
    /// <param name="availableSize"></param> 
    /// <returns></returns> 
    protected override Size MeasureOverride(Size availableSize) 
    { 
     var availableSizeOnThisLine = new Rect(new Point(0, 0), new Size(availableSize.Width, 0)); 
     var panelDesiredSize = new Size(availableSize.Width, 0); 

     foreach (FrameworkElement child in InternalChildren) 
     { 
      child.Measure(availableSize); 
      var childSize = child.DesiredSize; 

      if (childSize.Width > availableSizeOnThisLine.Size.Width) 
      { 
       // this child will overflow this line: New line! 
       panelDesiredSize.Height += availableSizeOnThisLine.Height; 
       availableSizeOnThisLine = new Rect(new Point(0, panelDesiredSize.Height), new Size(availableSize.Width, childSize.Height)); 

       availableSizeOnThisLine.Width -= childSize.Width; // subtract this area/width 
       availableSizeOnThisLine.Height = childSize.Height; 
      } 
      else 
      { 
       // this child will fit on this line.. 
       var thisChildRectangle = new Rect(childSize); 
       if (child.HorizontalAlignment == HorizontalAlignment.Left) 
       { 
        thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top); 
        availableSizeOnThisLine.Location.Offset(childSize.Width, 0); // move to the right 
       } 
       else if (child.HorizontalAlignment == HorizontalAlignment.Right) 
       { 
        thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - childSize.Width, availableSizeOnThisLine.Top); 
       } 

       child.Arrange(thisChildRectangle); 
       availableSizeOnThisLine.Width -= childSize.Width; // subtract child's width from avbailable space 
       availableSizeOnThisLine.Height = Math.Max(availableSizeOnThisLine.Height, childSize.Height); 

       panelDesiredSize.Height = Math.Max(childSize.Height, panelDesiredSize.Height); 
      } 
     } 

     return panelDesiredSize; 
    } 


    /// <summary> 
    /// parents position their children and tell their children how much size they are actually getting 
    /// </summary> 
    /// <param name="finalSize"></param> 
    /// <returns></returns> 
    protected override Size ArrangeOverride(Size finalSize) 
    { 
     var availableSizeOnThisLine = new Rect(new Point(0, 0), new Size(finalSize.Width, 0)); 

     foreach (FrameworkElement child in InternalChildren) 
     { 
      var childSize = child.DesiredSize; 

      if (childSize.Width > availableSizeOnThisLine.Size.Width) 
      { 
       // going to wrap around 
       var thisChildRectangle = new Rect(child.DesiredSize); 
       availableSizeOnThisLine = new Rect(new Point(0, availableSizeOnThisLine.Height), new Size(finalSize.Width, childSize.Height)); 

       if (child.HorizontalAlignment == HorizontalAlignment.Right) 
       { 
        thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - thisChildRectangle.Width, availableSizeOnThisLine.Top); 
       } 
       else if (child.HorizontalAlignment == HorizontalAlignment.Left) 
       { 
        thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top); 
       } 

       child.Arrange(thisChildRectangle); 
      } 
      else 
      { 
       // put on this line 
       var thisChildRectangle = new Rect(child.DesiredSize); 
       if (child.HorizontalAlignment == HorizontalAlignment.Right) 
       { 
        thisChildRectangle.Location = new Point(availableSizeOnThisLine.Right - thisChildRectangle.Width, availableSizeOnThisLine.Top); 
       } 
       else if (child.HorizontalAlignment == HorizontalAlignment.Left) 
       { 
        thisChildRectangle.Location = new Point(availableSizeOnThisLine.Left, availableSizeOnThisLine.Top); 
       } 

       child.Arrange(thisChildRectangle); 
       availableSizeOnThisLine.Width -= thisChildRectangle.Width; // subtract child's width from avbailable space 
      } 
      availableSizeOnThisLine.Height = Math.Max(childSize.Height, availableSizeOnThisLine.Height); 
     } 

     return finalSize; 
    } 
Смежные вопросы