【问题标题】:WPF - How can I center all items in a WrapPanel?WPF - 如何在 WrapPanel 中居中所有项目?
【发布时间】:2010-10-22 20:22:51
【问题描述】:

我使用WrapPanel 作为ItemsControlItemsPanel。现在,控件中的项目如下所示:

|1234567  |
|890      |

我希望它们像这样包装:

| 1234567 |
|   890   |

从概念上讲,布局过程应对齐每行项目,使其在WrapPanel 的边界内居中。

有人能解释一下这是怎么可能的吗?

【问题讨论】:

    标签: .net wpf layout center wrappanel


    【解决方案1】:

    内置的WrapPanel 不允许你对齐它的内容——只有它自己。这是一种允许您设置HorizontalContentAlignment的技术:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    public class AlignableWrapPanel : Panel
    {
        public HorizontalAlignment HorizontalContentAlignment
        {
            get { return (HorizontalAlignment)GetValue(HorizontalContentAlignmentProperty); }
            set { SetValue(HorizontalContentAlignmentProperty, value); }
        }
    
        public static readonly DependencyProperty HorizontalContentAlignmentProperty =
            DependencyProperty.Register("HorizontalContentAlignment", typeof(HorizontalAlignment), typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(HorizontalAlignment.Left, FrameworkPropertyMetadataOptions.AffectsArrange));
    
        protected override Size MeasureOverride(Size constraint)
        {
            Size curLineSize = new Size();
            Size panelSize = new Size();
    
            UIElementCollection children = base.InternalChildren;
    
            for (int i = 0; i < children.Count; i++)
            {
                UIElement child = children[i] as UIElement;
    
                // Flow passes its own constraint to children
                child.Measure(constraint);
                Size sz = child.DesiredSize;
    
                if (curLineSize.Width + sz.Width > constraint.Width) //need to switch to another line
                {
                    panelSize.Width = Math.Max(curLineSize.Width, panelSize.Width);
                    panelSize.Height += curLineSize.Height;
                    curLineSize = sz;
    
                    if (sz.Width > constraint.Width) // if the element is wider then the constraint - give it a separate line                    
                    {
                        panelSize.Width = Math.Max(sz.Width, panelSize.Width);
                        panelSize.Height += sz.Height;
                        curLineSize = new Size();
                    }
                }
                else //continue to accumulate a line
                {
                    curLineSize.Width += sz.Width;
                    curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
                }
            }
    
            // the last line size, if any need to be added
            panelSize.Width = Math.Max(curLineSize.Width, panelSize.Width);
            panelSize.Height += curLineSize.Height;
    
            return panelSize;
        }
    
        protected override Size ArrangeOverride(Size arrangeBounds)
        {
            int firstInLine = 0;
            Size curLineSize = new Size();
            double accumulatedHeight = 0;
            UIElementCollection children = this.InternalChildren;
    
            for (int i = 0; i < children.Count; i++)
            {
                Size sz = children[i].DesiredSize;
    
                if (curLineSize.Width + sz.Width > arrangeBounds.Width) //need to switch to another line
                {
                    ArrangeLine(accumulatedHeight, curLineSize, arrangeBounds.Width, firstInLine, i);
    
                    accumulatedHeight += curLineSize.Height;
                    curLineSize = sz;
    
                    if (sz.Width > arrangeBounds.Width) //the element is wider then the constraint - give it a separate line                    
                    {
                        ArrangeLine(accumulatedHeight, sz, arrangeBounds.Width, i, ++i);
                        accumulatedHeight += sz.Height;
                        curLineSize = new Size();
                    }
                    firstInLine = i;
                }
                else //continue to accumulate a line
                {
                    curLineSize.Width += sz.Width;
                    curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
                }
            }
    
            if (firstInLine < children.Count)
                ArrangeLine(accumulatedHeight, curLineSize, arrangeBounds.Width, firstInLine, children.Count);
    
            return arrangeBounds;
        }
    
        private void ArrangeLine(double y, Size lineSize, double boundsWidth, int start, int end)
        {
            double x = 0;
            if (this.HorizontalContentAlignment == HorizontalAlignment.Center)
            {
                x = (boundsWidth - lineSize.Width) / 2;
            }
            else if (this.HorizontalContentAlignment == HorizontalAlignment.Right)
            {
                x = (boundsWidth - lineSize.Width);
            }
    
            UIElementCollection children = InternalChildren;
            for (int i = start; i < end; i++)
            {
                UIElement child = children[i];
                child.Arrange(new Rect(x, y, child.DesiredSize.Width, lineSize.Height));
                x += child.DesiredSize.Width;
            }
        }
    }
    

    【讨论】:

    • 好课,谢谢!如果孩子有一个,我已经对其进行了调整以尊重FrameworkElement.HorizontalAlignment 的值:gist.github.com/gmanny/7450651(仅更改了ArrangeLine 方法)。
    • 对于拉伸对齐: if (i == end - 1 && Horizo​​ntalContentAlignment == Horizo​​ntalAlignment.Stretch) { child.Arrange(new Rect(x, y, boundsWidth - x, lineSize.Height)); } else { child.Arrange(new Rect(x, y, child.DesiredSize.Width, lineSize.Height)); x += child.DesiredSize.Width; }
    • 完美的一个。谢谢
    • 是否可以从中提取一个新方法,该方法在调用时会插入换行符?当我做了一些hacky代码来欺骗MeasureOverride认为它需要包装但我希望它在side方法中正常工作时,我只能让它这样做。
    • 对不起。我是个十足的菜鸟。我如何使用它?
    【解决方案2】:

    不幸的是,普通 WrapPanel 无法满足您的要求,因为它的目的是在包装之前水平(或垂直)填充所有可用空间。您可能必须设计自己的 WrapPanel 来处理这种情况。你可以从this sample that shows how to create your own WrapPanel开始。

    【讨论】:

      【解决方案3】:

      VerticalContentAlignment 版本(用于垂直面板):

      public class AlignableWrapPanel : Panel {
          public AlignableWrapPanel() {
              _orientation = Orientation.Horizontal;
          }
      
          private static bool IsWidthHeightValid(object value) {
              var v = (double)value;
              return (double.IsNaN(v)) || (v >= 0.0d && !double.IsPositiveInfinity(v));
          }
      
          public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(double),
                  typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure),
                  IsWidthHeightValid);
      
          [TypeConverter(typeof(LengthConverter))]
          public double ItemWidth {
              get { return (double)GetValue(ItemWidthProperty); }
              set { SetValue(ItemWidthProperty, value); }
          }
      
          public static readonly DependencyProperty ItemHeightProperty = DependencyProperty.Register("ItemHeight", typeof(double),
                  typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure),
                  IsWidthHeightValid);
      
          [TypeConverter(typeof(LengthConverter))]
          public double ItemHeight {
              get { return (double)GetValue(ItemHeightProperty); }
              set { SetValue(ItemHeightProperty, value); }
          }
      
          public static readonly DependencyProperty OrientationProperty = StackPanel.OrientationProperty.AddOwner(typeof(AlignableWrapPanel),
                  new FrameworkPropertyMetadata(Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure, OnOrientationChanged));
      
          public Orientation Orientation {
              get { return _orientation; }
              set { SetValue(OrientationProperty, value); }
          }
      
          private static void OnOrientationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
              var p = (AlignableWrapPanel)d;
              p._orientation = (Orientation)e.NewValue;
          }
      
          private Orientation _orientation;
      
          private struct UvSize {
              internal UvSize(Orientation orientation, double width, double height) {
                  U = V = 0d;
                  _orientation = orientation;
                  Width = width;
                  Height = height;
              }
      
              internal UvSize(Orientation orientation) {
                  U = V = 0d;
                  _orientation = orientation;
              }
      
              internal double U;
              internal double V;
              private readonly Orientation _orientation;
      
              internal double Width {
                  get { return (_orientation == Orientation.Horizontal ? U : V); }
                  private set { if (_orientation == Orientation.Horizontal) U = value; else V = value; }
              }
      
              internal double Height {
                  get { return (_orientation == Orientation.Horizontal ? V : U); }
                  private set { if (_orientation == Orientation.Horizontal) V = value; else U = value; }
              }
          }
      
          protected override Size MeasureOverride(Size constraint) {
              var curLineSize = new UvSize(Orientation);
              var panelSize = new UvSize(Orientation);
              var uvConstraint = new UvSize(Orientation, constraint.Width, constraint.Height);
              var itemWidth = ItemWidth;
              var itemHeight = ItemHeight;
              var itemWidthSet = !double.IsNaN(itemWidth);
              var itemHeightSet = !double.IsNaN(itemHeight);
      
              var childConstraint = new Size(
                      (itemWidthSet ? itemWidth : constraint.Width),
                      (itemHeightSet ? itemHeight : constraint.Height));
      
              var children = InternalChildren;
      
              for (int i = 0, count = children.Count; i < count; i++) {
                  var child = children[i];
                  if (child == null) continue;
      
                  //Flow passes its own constrint to children 
                  child.Measure(childConstraint);
      
                  //this is the size of the child in UV space 
                  var sz = new UvSize(
                          Orientation,
                          (itemWidthSet ? itemWidth : child.DesiredSize.Width),
                          (itemHeightSet ? itemHeight : child.DesiredSize.Height));
      
                  if (curLineSize.U + sz.U > uvConstraint.U) {
                      //need to switch to another line 
                      panelSize.U = Math.Max(curLineSize.U, panelSize.U);
                      panelSize.V += curLineSize.V;
                      curLineSize = sz;
      
                      if (!(sz.U > uvConstraint.U)) continue;
                      //the element is wider then the constrint - give it a separate line
                      panelSize.U = Math.Max(sz.U, panelSize.U);
                      panelSize.V += sz.V;
                      curLineSize = new UvSize(Orientation);
                  } else {
                      //continue to accumulate a line
                      curLineSize.U += sz.U;
                      curLineSize.V = Math.Max(sz.V, curLineSize.V);
                  }
              }
      
              //the last line size, if any should be added 
              panelSize.U = Math.Max(curLineSize.U, panelSize.U);
              panelSize.V += curLineSize.V;
      
              //go from UV space to W/H space
              return new Size(panelSize.Width, panelSize.Height);
          }
      
          protected override Size ArrangeOverride(Size finalSize) {
              var firstInLine = 0;
              var itemWidth = ItemWidth;
              var itemHeight = ItemHeight;
              double accumulatedV = 0;
              var itemU = (Orientation == Orientation.Horizontal ? itemWidth : itemHeight);
              var curLineSize = new UvSize(Orientation);
              var uvFinalSize = new UvSize(Orientation, finalSize.Width, finalSize.Height);
              var itemWidthSet = !double.IsNaN(itemWidth);
              var itemHeightSet = !double.IsNaN(itemHeight);
              var useItemU = (Orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet);
      
              var children = InternalChildren;
      
              for (int i = 0, count = children.Count; i < count; i++) {
                  var child = children[i];
                  if (child == null) continue;
      
                  var sz = new UvSize(
                          Orientation,
                          (itemWidthSet ? itemWidth : child.DesiredSize.Width),
                          (itemHeightSet ? itemHeight : child.DesiredSize.Height));
      
                  if (curLineSize.U + sz.U > uvFinalSize.U) {
                      //need to switch to another line 
                      ArrangeLine(finalSize, accumulatedV, curLineSize, firstInLine, i, useItemU, itemU);
      
                      accumulatedV += curLineSize.V;
                      curLineSize = sz;
      
                      if (sz.U > uvFinalSize.U) {
                          //the element is wider then the constraint - give it a separate line 
                          //switch to next line which only contain one element 
                          ArrangeLine(finalSize, accumulatedV, sz, i, ++i, useItemU, itemU);
      
                          accumulatedV += sz.V;
                          curLineSize = new UvSize(Orientation);
                      }
      
                      firstInLine = i;
                  } else {
                      //continue to accumulate a line
                      curLineSize.U += sz.U;
                      curLineSize.V = Math.Max(sz.V, curLineSize.V);
                  }
              }
      
              //arrange the last line, if any
              if (firstInLine < children.Count) {
                  ArrangeLine(finalSize, accumulatedV, curLineSize, firstInLine, children.Count, useItemU, itemU);
              }
      
              return finalSize;
          }
      
          private void ArrangeLine(Size finalSize, double v, UvSize line, int start, int end, bool useItemU, double itemU) {
              double u;
              var isHorizontal = Orientation == Orientation.Horizontal;
      
              if (_orientation == Orientation.Vertical) {
                  switch (VerticalContentAlignment) {
                      case VerticalAlignment.Center:
                          u = (finalSize.Height - line.U) / 2;
                          break;
                      case VerticalAlignment.Bottom:
                          u = finalSize.Height - line.U;
                          break;
                      default:
                          u = 0;
                          break;
                  }
              } else {
                  switch (HorizontalContentAlignment) {
                      case HorizontalAlignment.Center:
                          u = (finalSize.Width - line.U) / 2;
                          break;
                      case HorizontalAlignment.Right:
                          u = finalSize.Width - line.U;
                          break;
                      default:
                          u = 0;
                          break;
                  }
              }
      
              var children = InternalChildren;
              for (var i = start; i < end; i++) {
                  var child = children[i];
                  if (child == null) continue;
                  var childSize = new UvSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height);
                  var layoutSlotU = (useItemU ? itemU : childSize.U);
                  child.Arrange(new Rect(
                          isHorizontal ? u : v,
                          isHorizontal ? v : u,
                          isHorizontal ? layoutSlotU : line.V,
                          isHorizontal ? line.V : layoutSlotU));
                  u += layoutSlotU;
              }
          }
      
          public static readonly DependencyProperty HorizontalContentAlignmentProperty = DependencyProperty.Register(nameof(HorizontalContentAlignment), typeof(HorizontalAlignment),
                  typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(HorizontalAlignment.Left, FrameworkPropertyMetadataOptions.AffectsArrange));
      
          public HorizontalAlignment HorizontalContentAlignment {
              get { return (HorizontalAlignment)GetValue(HorizontalContentAlignmentProperty); }
              set { SetValue(HorizontalContentAlignmentProperty, value); }
          }
      
          public static readonly DependencyProperty VerticalContentAlignmentProperty = DependencyProperty.Register(nameof(VerticalContentAlignment), typeof(VerticalAlignment),
                  typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(VerticalAlignment.Top, FrameworkPropertyMetadataOptions.AffectsArrange));
      
          public VerticalAlignment VerticalContentAlignment {
              get { return (VerticalAlignment)GetValue(VerticalContentAlignmentProperty); }
              set { SetValue(VerticalContentAlignmentProperty, value); }
          }
      }
      

      【讨论】:

      • 由于某种原因,此解决方案有效,但接受的答案无效。谢谢你。
      【解决方案4】:

      简单的答案是您无法将 WrapPanel 的内容居中对齐。您可以将面板本身居中对齐,但最后一行仍将在面板内左对齐。

      改变建议:

      对行和列使用网格。如果您不是动态地将项目添加到集合中,这可能会很好地工作。

      创建您自己的 WrapPanel 版本,按照您需要的方式工作。 This MSDN document 描述了面板的工作原理,并包含有关创建自定义面板的部分。它还有一个指向示例自定义面板的链接。

      【讨论】:

        【解决方案5】:

        这是 Silverlight 版本

        特别感谢@DTig

        using System.Windows.Controls;
        using System.Windows;
        using Telerik.Windows;
        using System;
        using System.Linq;
        
        public class AlignableWrapPanel : Panel
        {
            public HorizontalAlignment HorizontalContentAlignment
            {
                get { return (HorizontalAlignment)GetValue(HorizontalContentAlignmentProperty); }
                set { SetValue(HorizontalContentAlignmentProperty, value); }
            }
        
            public static readonly DependencyProperty HorizontalContentAlignmentProperty =
                DependencyProperty.Register("HorizontalContentAlignment", typeof(HorizontalAlignment), typeof(AlignableWrapPanel), new FrameworkPropertyMetadata(HorizontalAlignment.Left, FrameworkPropertyMetadataOptions.AffectsArrange));
        
            protected override Size MeasureOverride(Size constraint)
            {
                Size curLineSize = new Size();
                Size panelSize = new Size();
        
                UIElementCollection children = base.Children;
        
                for (int i = 0; i < children.Count; i++)
                {
                    UIElement child = children[i] as UIElement;
        
                    // Flow passes its own constraint to children
                    child.Measure(constraint);
                    Size sz = child.DesiredSize;
        
                    if (curLineSize.Width + sz.Width > constraint.Width) //need to switch to another line
                    {
                        panelSize.Width = Math.Max(curLineSize.Width, panelSize.Width);
                        panelSize.Height += curLineSize.Height;
                        curLineSize = sz;
        
                        if (sz.Width > constraint.Width) // if the element is wider then the constraint - give it a separate line                    
                        {
                            panelSize.Width = Math.Max(sz.Width, panelSize.Width);
                            panelSize.Height += sz.Height;
                            curLineSize = new Size();
                        }
                    }
                    else //continue to accumulate a line
                    {
                        curLineSize.Width += sz.Width;
                        curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
                    }
                }
        
                // the last line size, if any need to be added
                panelSize.Width = Math.Max(curLineSize.Width, panelSize.Width);
                panelSize.Height += curLineSize.Height;
        
                return panelSize;
            }
        
            protected override Size ArrangeOverride(Size arrangeBounds)
            {
                int firstInLine = 0;
                Size curLineSize = new Size();
                double accumulatedHeight = 0;
                UIElementCollection children = this.Children;
        
                for (int i = 0; i < children.Count; i++)
                {
                    Size sz = children[i].DesiredSize;
        
                    if (curLineSize.Width + sz.Width > arrangeBounds.Width) //need to switch to another line
                    {
                        ArrangeLine(accumulatedHeight, curLineSize, arrangeBounds.Width, firstInLine, i);
        
                        accumulatedHeight += curLineSize.Height;
                        curLineSize = sz;
        
                        if (sz.Width > arrangeBounds.Width) //the element is wider then the constraint - give it a separate line                    
                        {
                            ArrangeLine(accumulatedHeight, sz, arrangeBounds.Width, i, ++i);
                            accumulatedHeight += sz.Height;
                            curLineSize = new Size();
                        }
                        firstInLine = i;
                    }
                    else //continue to accumulate a line
                    {
                        curLineSize.Width += sz.Width;
                        curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
                    }
                }
        
                if (firstInLine < children.Count)
                    ArrangeLine(accumulatedHeight, curLineSize, arrangeBounds.Width, firstInLine, children.Count);
        
                return arrangeBounds;
            }
        
            private void ArrangeLine(double y, Size lineSize, double boundsWidth, int start, int end)
            {
                double x = 0;
                if (this.HorizontalContentAlignment == HorizontalAlignment.Center)
                {
                    x = (boundsWidth - lineSize.Width) / 2;
                }
                else if (this.HorizontalContentAlignment == HorizontalAlignment.Right)
                {
                    x = (boundsWidth - lineSize.Width);
                }
        
                UIElementCollection children = Children;
                for (int i = start; i < end; i++)
                {
                    UIElement child = children[i];
                    var rect = new System.Windows.Rect(x, y, child.DesiredSize.Width, lineSize.Height);
                    child.Arrange(rect);
                    x += child.DesiredSize.Width;
                }
            }
        }
        

        【讨论】:

          【解决方案6】:

          我需要一个可以拉伸其内容的 WrapPanel,因此基于https://stackoverflow.com/a/7747002/121122 和一些摆弄我想出了这个:

          public class AlignableWrapPanel : Panel
          {
              public HorizontalAlignment HorizontalContentAlignment
              {
                  get => (HorizontalAlignment)GetValue(HorizontalContentAlignmentProperty);
                  set => SetValue(HorizontalContentAlignmentProperty, value);
              }
          
              public static readonly DependencyProperty HorizontalContentAlignmentProperty = DependencyProperty.Register(
                  nameof(HorizontalContentAlignment),
                  typeof(HorizontalAlignment),
                  typeof(AlignableWrapPanel),
                  new FrameworkPropertyMetadata(HorizontalAlignment.Left, FrameworkPropertyMetadataOptions.AffectsArrange));
          
              protected override Size MeasureOverride(Size constraint)
              {
                  var curLineSize = new Size();
                  var panelSize = new Size();
          
                  var children = InternalChildren;
          
                  for (var i = 0; i < children.Count; i++)
                  {
                      var child = children[i];
          
                      // flow passes its own constraint to children
                      child.Measure(constraint);
                      var sz = child.DesiredSize;
          
                      if (curLineSize.Width + sz.Width > constraint.Width) // need to switch to another line
                      {
                          panelSize.Width = Math.Max(curLineSize.Width, panelSize.Width);
                          panelSize.Height += curLineSize.Height;
                          curLineSize = sz;
          
                          if (sz.Width > constraint.Width) // if the element is wider then the constraint - give it a separate line                    
                          {
                              panelSize.Width = Math.Max(sz.Width, panelSize.Width);
                              panelSize.Height += sz.Height;
                              curLineSize = new Size();
                          }
                      }
                      else // continue to add to the line
                      {
                          curLineSize.Width += sz.Width;
                          curLineSize.Height = Math.Max(sz.Height, curLineSize.Height);
                      }
                  }
          
                  // the last line size, if any need to be added
                  panelSize.Width = Math.Max(curLineSize.Width, panelSize.Width);
                  panelSize.Height += curLineSize.Height;
          
                  return panelSize;
              }
          
              protected override Size ArrangeOverride(Size arrangeBounds)
              {
                  var firstInLine = 0;
                  var curLineSize = new Size();
                  var accumulatedHeight = 0D;
                  var children = InternalChildren;
          
                  for (var i = 0; i < children.Count; i++)
                  {
                      var desiredSize = children[i].DesiredSize;
          
                      if (curLineSize.Width + desiredSize.Width > arrangeBounds.Width) // need to switch to another line
                      {
                          ArrangeLine(accumulatedHeight, curLineSize, arrangeBounds.Width, firstInLine, i);
          
                          accumulatedHeight += curLineSize.Height;
                          curLineSize = desiredSize;
          
                          if(
                              desiredSize.Width > arrangeBounds.Width || 
                              children[i] is FrameworkElement element && element.HorizontalAlignment == HorizontalAlignment.Stretch)
                          {
                              // the element is wider then the constraint or it stretches - give it a separate line
                              ArrangeLine(accumulatedHeight, desiredSize, arrangeBounds.Width, i, ++i);
                              accumulatedHeight += desiredSize.Height;
                              curLineSize = new Size();
                          }
                          firstInLine = i;
                      }
                      else // continue to add to the line
                      {
                          curLineSize.Width += desiredSize.Width;
                          curLineSize.Height = Math.Max(desiredSize.Height, curLineSize.Height);
                      }
                  }
          
                  if (firstInLine < children.Count)
                  {
                      ArrangeLine(accumulatedHeight, curLineSize, arrangeBounds.Width, firstInLine, children.Count);
                  }
          
                  return arrangeBounds;
              }
          
              private void ArrangeLine(double y, Size lineSize, double boundsWidth, int start, int end)
              {
                  var children = InternalChildren;
          
                  var x = 0D;
                  if (HorizontalContentAlignment == HorizontalAlignment.Center)
                  {
                      x = (boundsWidth - lineSize.Width) / 2;
                  }
                  else if (HorizontalContentAlignment == HorizontalAlignment.Right)
                  {
                      x = boundsWidth - lineSize.Width;
                  }
          
                  var stretchChildren = new List<UIElement>();
                  for (var i = start; i < end; i++)
                  {
                      var child = children[i];
                      if (child is FrameworkElement element && element.HorizontalAlignment == HorizontalAlignment.Stretch)
                      {
                          stretchChildren.Add(child);
                      }
                  }
          
                  var spaceAvailableForStretchChildren = boundsWidth - lineSize.Width;
                  var spaceAvailablePerStretchChild = 0D;
                  if (stretchChildren.Any())
                  {
                      x = 0; // all available space will be filled so start at 0
                      spaceAvailablePerStretchChild = spaceAvailableForStretchChildren / stretchChildren.Count;
                      spaceAvailablePerStretchChild = spaceAvailablePerStretchChild >= 0 ? spaceAvailablePerStretchChild : 0;
                  }
          
                  for (var i = start; i < end; i++)
                  {
                      var child = children[i];
                      double itemWidth;
                      if(stretchChildren.Contains(child))
                      {
                          itemWidth = child.DesiredSize.Width + spaceAvailablePerStretchChild;
                      }
                      else
                      {
                          itemWidth = child.DesiredSize.Width;
                      }
          
                      child.Arrange(new Rect(x, y, itemWidth, lineSize.Height));
                      x += itemWidth;
                  }
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-01
            相关资源
            最近更新 更多