2012-07-24 23 views
3

我需要配置包裝面板,我可以在其中設置最大行數或最大列數。在包裝面板中設置最大行數

這真的很有必要,我使用的是WPF 4.0。但另一天,我是programmin Metro應用程序,我記得它的一個控件有這個屬性,但在WPF中沒有(直到我知道)。

在WPF 4.0中是否存在這樣的控件?或者我需要創建一個新的?

+0

如果添加一個元素並且達到了所謂的最大行數,那麼會發生什麼情況?我們需要一個新行來顯示此元素? – GameAlchemist 2012-07-24 17:49:48

+2

也許你可以使用UniformGrid?例如'' – LPL 2012-07-24 18:18:58

回答

5

您可以設置ItemHeightItemWidth屬性來設置最大行數和列...

欲瞭解更多信息,看看here

0

我認爲你正在努力完成的WPF Grid是更好的解決方案。 通過設置網格行的特定計數,您可以模擬包裝面板的行爲,並且它更靈活。

<Grid> 
    <Grid.ColumnDefinitions> 
    <ColumDefinition Height="Auto"/> 
    <ColumDefinition Height="Auto"/> 
    <ColumDefinition Height="Auto"/> 
    .... 
    <ColumDefinition Height="*/> 
    </Grid.ColumnDefinitions> 
<Grid> 
0

我能想到你能做到這一點的唯一方法與WrapPanel是如果你知道對象的大小(和他們是一致的),所以你可以相應地設置WrapPanel的高度/寬度。雖然這很醜陋。

有一件事要考慮:你想讓面板對超出最大行數/列數的元素做什麼?還是總是有正確數量的元素?如果是這樣的話,那麼你應該看看網格。

2

這裏是這樣一個WrapPanel的實現

的XAML:

<loc:WrapPanelWithRowsOrColumnsCount 
    xmlns:loc="clr-namespace:..." 
    Orientation="Vertical" 
    RowsOrColumnsCount="2"> 
    <TextBox Text="Andrew" Margin="2" Height="30" /> 
    <TextBox Text="Betty" Margin="2" Height="40" /> 
    <TextBox Text="Celine" Margin="2" Height="20" /> 
    <TextBox Text="Dick" Margin="2" Height="20" /> 
    <TextBox Text="Enron" Margin="2" Height="30" /> 
    <TextBox Text="Felix" Margin="2" Height="20" /> 
    <TextBox Text="Hanibal" Margin="2" Height="30" /> 
</loc:WrapPanelWithRowsOrColumnsCount> 

結果:WrapPanelWithRowsOrColumnsCount.cs

enter image description here

代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows; 
using System.Windows.Controls; 

public class WrapPanelWithRowsOrColumnsCount : WrapPanel 
{ 
    public static readonly DependencyProperty RowsOrColumnsCountProperty = 
     DependencyProperty.Register(
      "RowsOrColumnsCount", 
      typeof(int), 
      typeof(WrapPanelWithRowsOrColumnsCount), 
      new PropertyMetadata(int.MaxValue)); 

    public int RowsOrColumnsCount 
    { 
     get { return (int)GetValue(RowsOrColumnsCountProperty); } 
     set { SetValue(RowsOrColumnsCountProperty, Math.Max(value, 1)); } 
    } 

    protected override Size MeasureOverride(Size availableSize) 
    { 
     if (Children.Count > 0) 
     { 
      Size newAvailableSize; 

      if (Orientation == Orientation.Horizontal) 
      { 
       var suitableWidth = EstimateSuitableRowOrColumnLength(Children.Cast<UIElement>(), 
                     true, 
                     availableSize, 
                     RowsOrColumnsCount); 

       newAvailableSize = 
        double.IsNaN(suitableWidth) || suitableWidth <= 0 
         ? availableSize 
         : new Size(Math.Min(suitableWidth, availableSize.Width), availableSize.Height); 
      } 
      else 
      { 
       var suitableHeigth = EstimateSuitableRowOrColumnLength(Children.Cast<UIElement>(), 
                     false, 
                     availableSize, 
                     RowsOrColumnsCount); 
       newAvailableSize = 
        double.IsNaN(suitableHeigth) || suitableHeigth <= 0 
         ? availableSize 
         : new Size(availableSize.Width, Math.Min(suitableHeigth, availableSize.Height)); 
      } 

      return base.MeasureOverride(newAvailableSize); 
     } 
     else 
     { 
      return base.MeasureOverride(availableSize); 
     } 
    } 

    private double EstimateSuitableRowOrColumnLength(IEnumerable<UIElement> elements, 
                 bool trueRowsFalseColumns, 
                 Size availableSize, 
                 int rowsOrColumnsCount) 
    { 
     var elementsList = elements.ToList(); 

     var desiredLengths = elementsList.Select(el => DesiredLength(el, availableSize, trueRowsFalseColumns)).ToList(); 

     var maxLength = desiredLengths.Where(length => !double.IsNaN(length)).Concat(new[] { 0.0 }).Max(); 

     if (maxLength <= 0.0) 
     { 
      return double.NaN; 
     } 

     var desiredLengthsRepaired = desiredLengths.Select(length => double.IsNaN(length) ? maxLength : length).ToList(); 

     var totalDesiredLength = desiredLengthsRepaired.Sum(); 

     var maxCount = Math.Min(rowsOrColumnsCount, elementsList.Count); 

     var suitableRowOrColumnLength = totalDesiredLength/maxCount; 

     double nextLengthIncrement; 

     while (CountRowsOrColumnsNumber(desiredLengthsRepaired, suitableRowOrColumnLength, out nextLengthIncrement) > maxCount) 
     { 
      suitableRowOrColumnLength += nextLengthIncrement; 
     } 

     suitableRowOrColumnLength = Math.Max(suitableRowOrColumnLength, desiredLengthsRepaired.Max()); 

     return suitableRowOrColumnLength; 
    } 

    private int CountRowsOrColumnsNumber(List<double> desiredLengths, double rowOrColumnLengthLimit, out double nextLengthIncrement) 
    { 
     int rowOrColumnCount = 1; 
     double currentCumulativeLength = 0; 
     bool nextNewRowOrColumn = false; 

     var minimalIncrement = double.MaxValue; 

     foreach (var desiredLength in desiredLengths) 
     { 
      if (nextNewRowOrColumn) 
      { 
       rowOrColumnCount++; 
       currentCumulativeLength = 0; 
       nextNewRowOrColumn = false; 
      } 

      if (currentCumulativeLength + desiredLength > rowOrColumnLengthLimit) 
      { 
       minimalIncrement = Math.Min(minimalIncrement, 
              currentCumulativeLength + desiredLength - rowOrColumnLengthLimit); 

       if (currentCumulativeLength == 0) 
       { 
        nextNewRowOrColumn = true; 
        currentCumulativeLength = 0; 
       } 
       else 
       { 
        rowOrColumnCount++; 
        currentCumulativeLength = desiredLength; 
       } 
      } 
      else 
      { 
       currentCumulativeLength += desiredLength; 
      } 
     } 

     nextLengthIncrement = minimalIncrement != double.MaxValue ? minimalIncrement : 1; 

     return rowOrColumnCount; 
    } 

    private double DesiredLength(UIElement el, Size availableSize, bool trueRowsFalseColumns) 
    { 
     el.Measure(availableSize); 
     Size next = el.DesiredSize; 

     var length = trueRowsFalseColumns ? next.Width : next.Height; 

     if (Double.IsInfinity(length) || 
      Double.IsNaN(length)) 
     { 
      return Double.NaN; 
     } 
     else 
     { 
      return length; 
     } 
    } 
} 

該解決方案受this codeproject article的啓發。