diff --git a/src/Ursa/Controls/ElasticWrapPanel.cs b/src/Ursa/Controls/ElasticWrapPanel.cs index d18fc2a..f41c0e3 100644 --- a/src/Ursa/Controls/ElasticWrapPanel.cs +++ b/src/Ursa/Controls/ElasticWrapPanel.cs @@ -102,9 +102,8 @@ public class ElasticWrapPanel : WrapPanel itemWidthSet ? itemWidth : 0, itemHeightSet ? itemHeight : 0); - for (int i = 0, count = children.Count; i < count; i++) + foreach (var child in children) { - var child = children[i]; UVSize sz; if (ElasticWrapPanel.GetIsFixToRB(child)) { @@ -200,138 +199,133 @@ public class ElasticWrapPanel : WrapPanel protected override Size ArrangeOverride(Size finalSize) { - //设否元素宽的设置,是否元素高度设置 - bool isItemWidthSet = !double.IsNaN(this.ItemWidth) && this.ItemWidth > 0; - bool isItemHeightSet = !double.IsNaN(this.ItemHeight) && this.ItemHeight > 0; + //是否元素宽度设置,是否元素高度设置 + bool itemWidthSet = !double.IsNaN(ItemWidth); + bool itemHeightSet = !double.IsNaN(ItemHeight); //这个给非空间测量大小 - UVSize itemSetSize = new UVSize(this.Orientation, - (isItemWidthSet ? this.ItemWidth : 0), - (isItemHeightSet ? this.ItemHeight : 0)); + UVSize itemSetSize = new UVSize(Orientation, + itemWidthSet ? ItemWidth : 0, + itemHeightSet ? ItemHeight : 0); - //给定的空间大小测量UVSize,用于没有ItemWidth和ItemHeight时候测量元素空间大小,FixToRB=True的元素也使用这个 - UVSize uvConstraint = new UVSize(Orientation, finalSize.Width, finalSize.Height); + //给定的空间大小测量 UVSize,用于没有 ItemWidth 和 ItemHeight 时候测量元素空间大小 + //FixToRB=True 的元素也使用这个 + UVSize uvFinalSize = new UVSize(Orientation, finalSize.Width, finalSize.Height); //用于存放同一方向的元素列/行 集合 - List lineUiCollection = new List(); + List lineUVCollection = new List(); #region 得到同一方向元素集合的集合 - //写一个If只是用于减少外层变量,反感的请将if注释 - //if (lineUiCollection != null) + //当前元素集合行/列 + UVCollection curLineUIs = new UVCollection(Orientation, itemSetSize); + + //遍历内部元素 + var children = Children; + foreach (var child in children) { - //当前元素集合行/列 - UVCollection curLineUis = new UVCollection(this.Orientation, itemSetSize); - - //遍历内部元素 - var children = Children; - for (int i = 0, count = children.Count; i < count; i++) + UVSize sz; + if (ElasticWrapPanel.GetIsFixToRB(child)) { - var child = children[i]; - // if (child.Visibility == Visibility.Collapsed) continue; - UVSize uvSize = new UVSize(); - if (ElasticWrapPanel.GetIsFixToRB(child)) + //此元素需要设置到固定靠右/底的型为操作,测量元素大小时需要放开 + sz = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); + double lengthCount = 1; + if (sz.U > 0 && itemSetSize.U > 0) { - //此元素需要设置到固定靠右/底的型为操作,测量元素大小时需要放开 - uvSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); - double lengthCount = 1; - if (uvSize.U > 0 && itemSetSize.U > 0) + if (sz.U < itemSetSize.U) { - if (uvSize.U < itemSetSize.U) - { - //保持比例 - uvSize.U = itemSetSize.U; - } - else - { - //设置了同方向中元素的长度,所以这里要按照比例 - lengthCount = Math.Ceiling(uvSize.U / itemSetSize.U); - //sz.U = lengthCount * ItemSetSize.U; - uvSize.U = Math.Min(uvSize.U, uvConstraint.U); - } - } - - if (uvSize.V > 0 && itemSetSize.V > 0 && uvSize.V < itemSetSize.V) - { - //设置了垂直方向元素长度,如果此元素空间需求小于,则按照ItemSetSize.V - uvSize.V = itemSetSize.V; - } - - if (MathUtilities.GreaterThan(curLineUis.TotalU + uvSize.U, uvConstraint.U)) - { - //当前同一 列/行 如果容纳 此元素空间将超出 - if (curLineUis.Count > 0) - { - lineUiCollection.Add(curLineUis); - } - - curLineUis = new UVCollection(Orientation, itemSetSize); - curLineUis.Add(child, uvSize, Convert.ToInt32(lengthCount)); + //保持比例 + sz.U = itemSetSize.U; } else { - //这里是元素空间足够 - curLineUis.Add(child, uvSize, Convert.ToInt32(lengthCount)); + //设置了同方向中元素的长度,所以这里要按照比例 + lengthCount = Math.Ceiling(sz.U / itemSetSize.U); + //sz.U = lengthCount * ItemSetSize.U; + sz.U = Math.Min(sz.U, uvFinalSize.U); + } + } + + if (sz.V > 0 && itemSetSize.V > 0 && sz.V < itemSetSize.V) + { + //设置了垂直方向元素长度,如果此元素空间需求小于,则按照ItemSetSize.V + sz.V = itemSetSize.V; + } + + if (MathUtilities.GreaterThan(curLineUIs.TotalU + sz.U, uvFinalSize.U)) + { + //当前同一 列/行 如果容纳 此元素空间将超出 + if (curLineUIs.Count > 0) + { + lineUVCollection.Add(curLineUIs); } - lineUiCollection.Add(curLineUis); - //下一个可能是换行元素....不管了以后闲得蛋疼再弄吧 - curLineUis = new UVCollection(Orientation, itemSetSize); + curLineUIs = new UVCollection(Orientation, itemSetSize); + curLineUIs.Add(child, sz, Convert.ToInt32(lengthCount)); } else { - uvSize = new UVSize(Orientation, - (isItemWidthSet ? this.ItemWidth : child.DesiredSize.Width), - (isItemHeightSet ? this.ItemHeight : child.DesiredSize.Height)); + //这里是元素空间足够 + curLineUIs.Add(child, sz, Convert.ToInt32(lengthCount)); + } - if (MathUtilities.GreaterThan(curLineUis.TotalU + uvSize.U, uvConstraint.U)) + lineUVCollection.Add(curLineUIs); + //下一个可能是换行元素....不管了以后闲得蛋疼再弄吧 + curLineUIs = new UVCollection(Orientation, itemSetSize); + } + else + { + sz = new UVSize(Orientation, + itemWidthSet ? ItemWidth : child.DesiredSize.Width, + itemHeightSet ? ItemHeight : child.DesiredSize.Height); + + if (MathUtilities.GreaterThan(curLineUIs.TotalU + sz.U, uvFinalSize.U)) // Need to switch to another line + { + //当前同一 列/行 如果容纳 此元素空间将超出 + if (curLineUIs.Count > 0) { - //当前同一 列/行 如果容纳 此元素空间将超出 - if (curLineUis.Count > 0) - { - lineUiCollection.Add(curLineUis); - } - - curLineUis = new UVCollection(Orientation, itemSetSize); - curLineUis.Add(child, uvSize); - if (MathUtilities.GreaterThan(uvSize.U, uvConstraint.U)) - { - lineUiCollection.Add(curLineUis); - curLineUis = new UVCollection(Orientation, itemSetSize); - } + lineUVCollection.Add(curLineUIs); } - else + + curLineUIs = new UVCollection(Orientation, itemSetSize); + curLineUIs.Add(child, sz); + if (MathUtilities.GreaterThan(sz.U, uvFinalSize.U)) { - //空间足够 - curLineUis.Add(child, uvSize); + lineUVCollection.Add(curLineUIs); + curLineUIs = new UVCollection(Orientation, itemSetSize); } } + else + { + //空间足够 + curLineUIs.Add(child, sz); + } } + } - if (curLineUis.Count > 0 && !lineUiCollection.Contains(curLineUis)) - { - lineUiCollection.Add(curLineUis); - } + if (curLineUIs.Count > 0 && !lineUVCollection.Contains(curLineUIs)) + { + lineUVCollection.Add(curLineUIs); } #endregion bool isFillU = false; bool isFillV = false; - switch (this.Orientation) + switch (Orientation) { case Orientation.Horizontal: - isFillU = this.IsFillHorizontal; - isFillV = this.IsFillVertical; + isFillU = IsFillHorizontal; + isFillV = IsFillVertical; break; case Orientation.Vertical: - isFillU = this.IsFillVertical; - isFillV = this.IsFillHorizontal; + isFillU = IsFillVertical; + isFillV = IsFillHorizontal; break; } - if (lineUiCollection.Count > 0) + if (lineUVCollection.Count > 0) { double accumulatedV = 0; double adaptULength = 0; @@ -341,10 +335,10 @@ public class ElasticWrapPanel : WrapPanel { if (itemSetSize.U > 0) { - int maxElementCount = lineUiCollection + int maxElementCount = lineUVCollection .Max(uiSet => uiSet.UICollection .Sum(p => p.Value.ULengthCount)); - adaptULength = (uvConstraint.U - maxElementCount * itemSetSize.U) / maxElementCount; + adaptULength = (uvFinalSize.U - maxElementCount * itemSetSize.U) / maxElementCount; adaptULength = Math.Max(adaptULength, 0); } } @@ -354,19 +348,19 @@ public class ElasticWrapPanel : WrapPanel if (itemSetSize.V > 0) { isAdaptV = true; - adaptVLength = uvConstraint.V / lineUiCollection.Count; + adaptVLength = uvFinalSize.V / lineUVCollection.Count; } } - bool isHorizontal = (Orientation == Orientation.Horizontal); - foreach (var lineUVCollection in lineUiCollection) + bool isHorizontal = Orientation == Orientation.Horizontal; + foreach (var uvCollection in lineUVCollection) { double u = 0; - var lineUiEles = lineUVCollection.UICollection.Keys.ToList(); - double linevV = isAdaptV ? adaptVLength : lineUVCollection.LineV; - foreach (var child in lineUiEles) + var lineUIEles = uvCollection.UICollection.Keys.ToList(); + double linevV = isAdaptV ? adaptVLength : uvCollection.LineV; + foreach (var child in lineUIEles) { - UVLengthSize childSize = lineUVCollection.UICollection[child]; + UVLengthSize childSize = uvCollection.UICollection[child]; double layoutSlotU = childSize.UVSize.U + childSize.ULengthCount * adaptULength; double layoutSlotV = isAdaptV ? linevV : childSize.UVSize.V; @@ -382,30 +376,30 @@ public class ElasticWrapPanel : WrapPanel { if (itemSetSize.U > 0) { - //说明同方向有宽度设置,这里尽量按照ItemULength保持 + //说明同方向有宽度设置,这里尽量按照 ItemULength 保持 layoutSlotU = childSize.ULengthCount * itemSetSize.U + childSize.ULengthCount * adaptULength; - double leaveULength = uvConstraint.U - u; + double leaveULength = uvFinalSize.U - u; layoutSlotU = Math.Min(leaveULength, layoutSlotU); } child.Arrange(new Rect( - (isHorizontal ? Math.Max(0, (uvConstraint.U - layoutSlotU)) : accumulatedV), - (isHorizontal ? accumulatedV : Math.Max(0, (uvConstraint.U - layoutSlotU))), - (isHorizontal ? layoutSlotU : layoutSlotV), - (isHorizontal ? layoutSlotV : layoutSlotU))); + isHorizontal ? Math.Max(0, uvFinalSize.U - layoutSlotU) : accumulatedV, + isHorizontal ? accumulatedV : Math.Max(0, uvFinalSize.U - layoutSlotU), + isHorizontal ? layoutSlotU : layoutSlotV, + isHorizontal ? layoutSlotV : layoutSlotU)); } u += layoutSlotU; } accumulatedV += linevV; - lineUiEles.Clear(); + lineUIEles.Clear(); } } - lineUiCollection.ForEach(col => col.Dispose()); - lineUiCollection.Clear(); + lineUVCollection.ForEach(col => col.Dispose()); + lineUVCollection.Clear(); return finalSize; } @@ -478,9 +472,9 @@ public class ElasticWrapPanel : WrapPanel public UVCollection(Orientation orientation, UVSize itemSetSize) { - this.UICollection = new Dictionary(); + UICollection = new Dictionary(); LineDesireUVSize = new UVSize(orientation); - this.ItemSetSize = itemSetSize; + ItemSetSize = itemSetSize; } public double TotalU => LineDesireUVSize.U; @@ -489,10 +483,10 @@ public class ElasticWrapPanel : WrapPanel public void Add(Control element, UVSize childSize, int itemULength = 1) { - if (this.UICollection.ContainsKey(element)) + if (UICollection.ContainsKey(element)) throw new InvalidOperationException("The element already exists and cannot be added repeatedly."); - this.UICollection[element] = new UVLengthSize(childSize, itemULength); + UICollection[element] = new UVLengthSize(childSize, itemULength); LineDesireUVSize.U += childSize.U; LineDesireUVSize.V = Math.Max(LineDesireUVSize.V, childSize.V); }