2012-06-19 9 views
4

У меня есть панель обертки, которая будет содержать переменное количество элементов управления.WPF WrapPanel Динамическая высота

Я хочу, чтобы ориентация была вертикальной (поскольку объекты внутри имеют фиксированную ширину, но с переменной высотой).

Но проблема, с которой я столкнулась, заключается в том, что при наличии полосы прокрутки высота является inifinite, поэтому элементы никогда не обертываются во второй столбец. Полоса прокрутки необходима, так как часто будет больше объектов, чем можно разместить на одном экране. Я могу остановить это, установив фиксированную высоту, но это не приемлемое решение, так как разумная фиксированная высота будет отличаться для каждого выбора.

По существу, мне нужен WrapPanel, высота которого динамически изменяется в зависимости от ширины панели и количества элементов, содержащихся внутри.

Для иллюстрации:

Если панель достаточно широк, чтобы показать 3 колонки будет:

| 1 5 9 |

| 2 6 - |

| 3 7 - | Высота = 4

| 4 8 - |

Но если пользователь изменяет размер окна до точки, где он может только разместить 2 колонки высота будет увеличиваться:

| 1 6 |

| 2 7 |

| 3 8 | Высота = 5

| 4 9 |

| 5 - |

Кроме того, я не уверен, насколько это возможно, но это я бы идеально, как для того, элементы horizonatally, но сохранить ориентацию по вертикали, так что они будут заказаны:

| 1 2 3 |

| 4 5 6 |

| 7 8 9 |

Может ли кто-нибудь сказать мне, как начать с этого? Я предполагаю, что это возможно с пользовательской реализацией WrapPanel, но я немного смущен, как начать.

Спасибо,

+0

Я не совсем уверен, что вы после этого, но увидеть, если это помогает Http: // StackOverflow. com/questions/9769618/how-can-we-set-the-wrap-point-for-the-wrappanel/9770590 # 9770590 – Phil

+0

Возможно, это может помочь вам, WrapGridPanel: http://stackoverflow.com/questions/ 4598377/некоторые предметы-МОФ-WrapPanel-с-имеющей-A-высоты-оф –

ответ

3

сведущих, чтобы достичь того, что мне нужно было с помощью следующего кода:

public class InvertedWrapPanel : WrapPanel 
{ 
    private int itemsPerRow = 0; 

    protected override Size MeasureOverride(Size availableSize) 
    { 
     if (Orientation == Orientation.Horizontal) 
     { 
      return base.MeasureOverride(availableSize); 
     } 
     else //Orientation is vertical 
     { 
      double w = availableSize.Width; 

      double maxChildWidth = 0; 

      foreach (UIElement child in Children) 
      { 
       //Get the current childs desired size parameters 
       child.Measure(availableSize); 

       //Store off the maximum child width 
       if (child.DesiredSize.Width > maxChildWidth) 
        maxChildWidth = child.DesiredSize.Width; 
      } 

      //See how many items we can fit in a row 
      itemsPerRow = Convert.ToInt32(Math.Floor(w/maxChildWidth)); 

      return base.MeasureOverride(availableSize); 
     } 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     if (Orientation == Orientation.Horizontal) 
     { 
      return base.ArrangeOverride(finalSize); 
     } 
     else //Orientation is vertical 
     { 
      double currentX = 0; 
      double currentY = 0; 

      int col = 0; 

      double lastX = 0; 
      double lastWidth = 0; 

      //Arrays to store differing column heights 
      double[] lastY = new double[itemsPerRow]; 
      double[] lastHeight = new double[itemsPerRow]; 

      double[] colHeights = new double[itemsPerRow]; 

      foreach (UIElement child in Children) 
      { 
       //If we've reached the end of a row 
       if (col >= itemsPerRow) 
       { 
        col = 0; 
        currentX = 0; //reset the x-coordinate for first column 
       } 
       else 
        currentX = lastX + lastWidth; //Increase the x-coordinate 

       //Increase the y-coordinates for the current column 
       currentY = lastY[col] + lastHeight[col]; 

       //Draw the element 
       child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height)); 

       //Store off the current child's parameters 
       lastX = currentX; 
       lastWidth = child.DesiredSize.Width; 

       lastY[col] = currentY; 
       lastHeight[col] = child.DesiredSize.Height; 

       colHeights[col] += child.DesiredSize.Height; 

       col++; 
      } 

      //Set the height of the panel to the max column height. 
      //Otherwise scroll bar will set height to infinity. 
      double maxHeight = 0; 

      foreach (double d in colHeights) 
      { 
       if (d > maxHeight) 
        maxHeight = d; 
      } 

      base.Height = maxHeight; 

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