11using System ;
2+ using System . Collections . Generic ;
23using System . Windows ;
34using System . Windows . Controls ;
5+ using System . Windows . Media ;
46using HandyControl . Data ;
57using HandyControl . Expression . Drawing ;
68
@@ -12,10 +14,12 @@ public class FlexPanel : Panel
1214
1315 private int _lineCount ;
1416
17+ private readonly List < FlexItemInfo > _orderList = new List < FlexItemInfo > ( ) ;
18+
1519 #region Item
1620
1721 public static readonly DependencyProperty OrderProperty = DependencyProperty . RegisterAttached (
18- "Order" , typeof ( int ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( ValueBoxes . Int0Box , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
22+ "Order" , typeof ( int ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( ValueBoxes . Int0Box , OnItemPropertyChanged ) ) ;
1923
2024 public static void SetOrder ( DependencyObject element , int value )
2125 => element . SetValue ( OrderProperty , value ) ;
@@ -24,7 +28,7 @@ public static int GetOrder(DependencyObject element)
2428 => ( int ) element . GetValue ( OrderProperty ) ;
2529
2630 public static readonly DependencyProperty FlexGrowProperty = DependencyProperty . RegisterAttached (
27- "FlexGrow" , typeof ( double ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( ValueBoxes . Double0Box , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
31+ "FlexGrow" , typeof ( double ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( ValueBoxes . Double0Box , OnItemPropertyChanged ) ) ;
2832
2933 public static void SetFlexGrow ( DependencyObject element , double value )
3034 => element . SetValue ( FlexGrowProperty , value ) ;
@@ -33,7 +37,7 @@ public static double GetFlexGrow(DependencyObject element)
3337 => ( double ) element . GetValue ( FlexGrowProperty ) ;
3438
3539 public static readonly DependencyProperty FlexShrinkProperty = DependencyProperty . RegisterAttached (
36- "FlexShrink" , typeof ( double ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( ValueBoxes . Double1Box , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
40+ "FlexShrink" , typeof ( double ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( ValueBoxes . Double1Box , OnItemPropertyChanged ) ) ;
3741
3842 public static void SetFlexShrink ( DependencyObject element , double value )
3943 => element . SetValue ( FlexShrinkProperty , value ) ;
@@ -42,7 +46,7 @@ public static double GetFlexShrink(DependencyObject element)
4246 => ( double ) element . GetValue ( FlexShrinkProperty ) ;
4347
4448 public static readonly DependencyProperty FlexBasisProperty = DependencyProperty . RegisterAttached (
45- "FlexBasis" , typeof ( double ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( double . NaN , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
49+ "FlexBasis" , typeof ( double ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( double . NaN , OnItemPropertyChanged ) ) ;
4650
4751 public static void SetFlexBasis ( DependencyObject element , double value )
4852 => element . SetValue ( FlexBasisProperty , value ) ;
@@ -51,7 +55,7 @@ public static double GetFlexBasis(DependencyObject element)
5155 => ( double ) element . GetValue ( FlexBasisProperty ) ;
5256
5357 public static readonly DependencyProperty AlignSelfProperty = DependencyProperty . RegisterAttached (
54- "AlignSelf" , typeof ( FlexItemAlignment ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( default ( FlexItemAlignment ) , FrameworkPropertyMetadataOptions . AffectsMeasure ) ) ;
58+ "AlignSelf" , typeof ( FlexItemAlignment ) , typeof ( FlexPanel ) , new FrameworkPropertyMetadata ( default ( FlexItemAlignment ) , OnItemPropertyChanged ) ) ;
5559
5660 public static void SetAlignSelf ( DependencyObject element , FlexItemAlignment value )
5761 => element . SetValue ( AlignSelfProperty , value ) ;
@@ -110,17 +114,33 @@ public FlexContentAlignment AlignContent
110114
111115 #endregion
112116
117+ private static void OnItemPropertyChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
118+ {
119+ if ( d is UIElement element )
120+ {
121+ if ( VisualTreeHelper . GetParent ( element ) is FlexPanel p )
122+ {
123+ p . InvalidateMeasure ( ) ;
124+ }
125+ }
126+ }
127+
113128 protected override Size MeasureOverride ( Size constraint )
114129 {
130+ _orderList . Clear ( ) ;
115131 var curLineSize = new UVSize ( FlexDirection ) ;
116132 var panelSize = new UVSize ( FlexDirection ) ;
117133 _uvConstraint = new UVSize ( FlexDirection , constraint ) ;
118134 var childConstraint = new Size ( constraint . Width , constraint . Height ) ;
119135 _lineCount = 1 ;
136+ var children = InternalChildren ;
120137
121- foreach ( UIElement child in InternalChildren )
138+ for ( var i = 0 ; i < children . Count ; i ++ )
122139 {
140+ var child = children [ i ] ;
123141 if ( child == null ) continue ;
142+
143+ _orderList . Add ( new FlexItemInfo ( i , GetOrder ( child ) ) ) ;
124144 child . Measure ( childConstraint ) ;
125145
126146 var sz = new UVSize ( FlexDirection , child . DesiredSize ) ;
@@ -155,6 +175,8 @@ protected override Size MeasureOverride(Size constraint)
155175 }
156176 }
157177
178+ _orderList . Sort ( ) ;
179+
158180 //the last line size, if any should be added
159181 panelSize . U = Math . Max ( curLineSize . U , panelSize . U ) ;
160182 panelSize . V += curLineSize . V ;
@@ -184,7 +206,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
184206 // calculate line max U space
185207 for ( var i = 0 ; i < children . Count ; i ++ )
186208 {
187- var child = children [ i ] ;
209+ var child = children [ _orderList [ i ] . Index ] ;
188210 if ( child == null ) continue ;
189211
190212 var sz = new UVSize ( FlexDirection , child . DesiredSize ) ;
@@ -341,7 +363,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
341363 // arrange line
342364 for ( var i = 0 ; i < children . Count ; i ++ )
343365 {
344- var child = children [ i ] ;
366+ var child = children [ _orderList [ i ] . Index ] ;
345367 if ( child == null ) continue ;
346368
347369 var sz = new UVSize ( FlexDirection , child . DesiredSize ) ;
@@ -465,7 +487,7 @@ private void ArrangeLine(FlexLineInfo lineInfo)
465487 var children = InternalChildren ;
466488 for ( int i = lineInfo . ItemStartIndex , j = 0 ; i < lineInfo . ItemEndIndex ; i ++ , j ++ )
467489 {
468- var child = children [ i ] ;
490+ var child = children [ _orderList [ i ] . Index ] ;
469491 if ( child == null ) continue ;
470492
471493 var childSize = new UVSize ( FlexDirection , isHorizontal ?
@@ -512,6 +534,21 @@ private void ArrangeLine(FlexLineInfo lineInfo)
512534 }
513535 }
514536
537+ private readonly struct FlexItemInfo : IComparable < FlexItemInfo >
538+ {
539+ public FlexItemInfo ( int index , int order )
540+ {
541+ Index = index ;
542+ Order = order ;
543+ }
544+
545+ private int Order { get ; }
546+
547+ public int Index { get ; }
548+
549+ public int CompareTo ( FlexItemInfo other ) => Order . CompareTo ( other . Order ) ;
550+ }
551+
515552 private struct FlexLineInfo
516553 {
517554 public double ItemsU { get ; set ; }
0 commit comments