1
- using NUnit . Framework ;
2
- using NUnit . Framework . Constraints ;
3
1
using System ;
4
2
using System . Collections . Generic ;
5
3
using System . Linq ;
6
4
using System . Reflection ;
5
+ using NUnit . Framework ;
6
+ using NUnit . Framework . Constraints ;
7
7
using Xamarin . Forms . Internals ;
8
8
9
9
namespace Xamarin . Forms . Core . UnitTests
@@ -108,6 +108,168 @@ public void StarRowsHaveEqualHeights()
108
108
Assert . That ( column0Height , Is . LessThan ( gridHeight ) ) ;
109
109
}
110
110
111
+ [ Test ]
112
+ public void StarRowsDoNotOverlapWithStackLayoutOnTop ( )
113
+ {
114
+ SetupStarRowOverlapTest ( rowAIsOnTop : false , out VisualElement rowAControl ,
115
+ out VisualElement rowBControl , out Label lastLabel ) ;
116
+
117
+ var bottomOfRowB = rowBControl . Y + rowBControl . Height ;
118
+ var bottomOfLastLabelInRowB = rowBControl . Y + lastLabel . Y + lastLabel . Height ;
119
+ var topOfRowA = rowAControl . Y ;
120
+
121
+ Assert . That ( bottomOfRowB , Is . EqualTo ( bottomOfLastLabelInRowB ) ) ;
122
+
123
+ Assert . That ( topOfRowA , Is . EqualTo ( bottomOfRowB ) ,
124
+ "B is on top of A, so the top of A should be the bottom of B" ) ;
125
+ }
126
+
127
+ [ Test ]
128
+ public void StarRowsDoNotOverlapWithStackLayoutOnBottom ( )
129
+ {
130
+ SetupStarRowOverlapTest ( rowAIsOnTop : true , out VisualElement rowAControl ,
131
+ out VisualElement rowBControl , out Label lastLabel ) ;
132
+
133
+ var topOfRowB = rowBControl . Y ;
134
+ var bottomOfRowB = rowBControl . Y + rowBControl . Height ;
135
+ var bottomOfLastLabelInRowB = rowBControl . Y + lastLabel . Y + lastLabel . Height ;
136
+ var bottomOfRowA = rowAControl . Y + rowAControl . Height ;
137
+
138
+ Assert . That ( bottomOfRowB , Is . EqualTo ( bottomOfLastLabelInRowB ) ) ;
139
+
140
+ Assert . That ( topOfRowB , Is . EqualTo ( bottomOfRowA ) ,
141
+ "A is on top of B, so the top of B should be the bottom of A" ) ;
142
+ }
143
+
144
+ [ Test ]
145
+ public void StarColumnsDoNotOverlapWithStackLayoutAtStart ( )
146
+ {
147
+ SetupStarColumnOverlapTest ( colAIsAtStart : false , out VisualElement colAControl ,
148
+ out VisualElement colBControl , out Label lastLabel ) ;
149
+
150
+ var endOfColB = colBControl . X + colBControl . Width ;
151
+ var endOfLastLabelInColB = colBControl . X + lastLabel . X + lastLabel . Width ;
152
+ var startOfColA = colAControl . X ;
153
+
154
+ Assert . That ( endOfColB , Is . EqualTo ( endOfLastLabelInColB ) ) ;
155
+
156
+ Assert . That ( startOfColA , Is . EqualTo ( endOfColB ) ,
157
+ "B is before A, so the start of A should be the end of B" ) ;
158
+ }
159
+
160
+ [ Test ]
161
+ public void StarColumnsDoNotOverlapWithStackLayoutAtEnd ( )
162
+ {
163
+ SetupStarColumnOverlapTest ( colAIsAtStart : true , out VisualElement colAControl ,
164
+ out VisualElement colBControl , out Label lastLabel ) ;
165
+
166
+ var startOfColB = colBControl . X ;
167
+ var endOfColB = colBControl . X + colBControl . Width ;
168
+ var endOfLastLabelInColB = colBControl . X + lastLabel . X + lastLabel . Width ;
169
+ var endOfColA = colAControl . X + colAControl . Width ;
170
+
171
+ Assert . That ( endOfColB , Is . EqualTo ( endOfLastLabelInColB ) ) ;
172
+
173
+ Assert . That ( endOfColA , Is . EqualTo ( startOfColB ) ,
174
+ "A is before B, so the end of A should be the start of B" ) ;
175
+ }
176
+
177
+ void SetupStarRowOverlapTest ( bool rowAIsOnTop , out VisualElement rowAControl ,
178
+ out VisualElement rowBControl , out Label lastLabel )
179
+ {
180
+ var grid = new Grid
181
+ {
182
+ RowSpacing = 0 ,
183
+ RowDefinitions = new RowDefinitionCollection
184
+ {
185
+ new RowDefinition ( ) { Height = GridLength . Star } ,
186
+ new RowDefinition ( ) { Height = GridLength . Star }
187
+ }
188
+ } ;
189
+
190
+ var labelSize = new Size ( 100 , 20 ) ;
191
+
192
+ Label label ;
193
+ rowAControl = label = new FixedSizeLabel ( labelSize ) { Text = "Hello" } ;
194
+
195
+ StackLayout stackLayout ;
196
+ rowBControl = stackLayout = new StackLayout ( ) { Spacing = 0 , IsPlatformEnabled = true } ;
197
+
198
+ for ( int n = 0 ; n < 14 ; n ++ )
199
+ {
200
+ var labelInStack = new FixedSizeLabel ( labelSize ) { Text = "Hello" } ;
201
+ stackLayout . Children . Add ( labelInStack ) ;
202
+ }
203
+
204
+ lastLabel = new FixedSizeLabel ( labelSize ) { Text = "Hello" } ;
205
+ stackLayout . Children . Add ( lastLabel ) ;
206
+
207
+ grid . Children . Add ( stackLayout ) ;
208
+ grid . Children . Add ( label ) ;
209
+
210
+ if ( rowAIsOnTop )
211
+ {
212
+ Grid . SetRow ( rowAControl , 0 ) ;
213
+ Grid . SetRow ( rowBControl , 1 ) ;
214
+ }
215
+ else
216
+ {
217
+ Grid . SetRow ( rowBControl , 0 ) ;
218
+ Grid . SetRow ( rowAControl , 1 ) ;
219
+ }
220
+
221
+ var sizeRequest = grid . Measure ( 300 , double . PositiveInfinity ) ;
222
+ grid . Layout ( new Rectangle ( 0 , 0 , sizeRequest . Request . Width , sizeRequest . Request . Height ) ) ;
223
+ }
224
+
225
+ void SetupStarColumnOverlapTest ( bool colAIsAtStart , out VisualElement colAControl ,
226
+ out VisualElement colBControl , out Label lastLabel )
227
+ {
228
+ var grid = new Grid
229
+ {
230
+ ColumnSpacing = 0 ,
231
+ ColumnDefinitions = new ColumnDefinitionCollection
232
+ {
233
+ new ColumnDefinition ( ) { Width = GridLength . Star } ,
234
+ new ColumnDefinition ( ) { Width = GridLength . Star }
235
+ }
236
+ } ;
237
+
238
+ var labelSize = new Size ( 20 , 100 ) ;
239
+
240
+ Label label ;
241
+ colAControl = label = new FixedSizeLabel ( labelSize ) { Text = "Hello" } ;
242
+
243
+ StackLayout stackLayout ;
244
+ colBControl = stackLayout = new StackLayout ( ) { Spacing = 0 , Orientation = StackOrientation . Horizontal , IsPlatformEnabled = true } ;
245
+
246
+ for ( int n = 0 ; n < 14 ; n ++ )
247
+ {
248
+ var labelInStack = new FixedSizeLabel ( labelSize ) { Text = "Hello" } ;
249
+ stackLayout . Children . Add ( labelInStack ) ;
250
+ }
251
+
252
+ lastLabel = new FixedSizeLabel ( labelSize ) { Text = "Hello" } ;
253
+ stackLayout . Children . Add ( lastLabel ) ;
254
+
255
+ grid . Children . Add ( stackLayout ) ;
256
+ grid . Children . Add ( label ) ;
257
+
258
+ if ( colAIsAtStart )
259
+ {
260
+ Grid . SetColumn ( colAControl , 0 ) ;
261
+ Grid . SetColumn ( colBControl , 1 ) ;
262
+ }
263
+ else
264
+ {
265
+ Grid . SetColumn ( colBControl , 0 ) ;
266
+ Grid . SetColumn ( colAControl , 1 ) ;
267
+ }
268
+
269
+ var sizeRequest = grid . Measure ( double . PositiveInfinity , 300 ) ;
270
+ grid . Layout ( new Rectangle ( 0 , 0 , sizeRequest . Request . Width , sizeRequest . Request . Height ) ) ;
271
+ }
272
+
111
273
[ Test ( Description = "Columns with a Star width less than one should not cause the Grid to contract below the target width; see https://github.com/xamarin/Xamarin.Forms/issues/11742" ) ]
112
274
public void StarWidthsLessThanOneShouldNotContractGrid ( )
113
275
{
@@ -176,8 +338,8 @@ public void ColumnsLessThanOneStarShouldBeTallerThanOneStarColumns()
176
338
177
339
var grid2 = new Grid ( ) { ColumnSpacing = 0 } ;
178
340
179
- // Because the column with the label in it is narrower in this grid (0.5* vs 1*), the label will have
180
- // grow taller to fit the text. So we expect this grid to grow vertically to accommodate it.
341
+ // Because the column with the label in it is narrower in this grid (0.5* vs 1*), the label will have
342
+ // grow taller to fit the text. So we expect this grid to grow vertically to accommodate it.
181
343
grid2 . ColumnDefinitions . Add ( new ColumnDefinition ( ) { Width = new GridLength ( 0.5 , GridUnitType . Star ) } ) ;
182
344
grid2 . ColumnDefinitions . Add ( new ColumnDefinition ( ) { Width = GridLength . Star } ) ;
183
345
@@ -224,7 +386,7 @@ public void ContentHeightSumShouldMatchGridHeightWithAutoRows()
224
386
}
225
387
226
388
[ Test ]
227
- public void UnconstrainedStarRowWithMultipleStarColumnsAllowsTextToGrow ( )
389
+ public void UnconstrainedStarRowWithMultipleStarColumnsAllowsTextToGrow ( )
228
390
{
229
391
var outerGrid = new Grid ( ) { ColumnSpacing = 0 , Padding = 0 , RowSpacing = 0 , IsPlatformEnabled = true } ;
230
392
outerGrid . RowDefinitions . Add ( new RowDefinition ( ) { Height = GridLength . Star } ) ;
@@ -235,10 +397,10 @@ public void UnconstrainedStarRowWithMultipleStarColumnsAllowsTextToGrow()
235
397
var sl = new StackLayout { Padding = 0 , IsPlatformEnabled = true } ;
236
398
237
399
var label1 = new HeightBasedOnTextLengthLabel
238
- {
400
+ {
239
401
Text = "The actual text here doesn't matter, just the length. The length determines the height."
240
402
} ;
241
-
403
+
242
404
var label2 = new ColumnTestLabel { FontSize = 13 , LineBreakMode = LineBreakMode . NoWrap , Text = "Description" } ;
243
405
244
406
sl . Children . Add ( label1 ) ;
@@ -293,8 +455,8 @@ public void AbsoluteColumnShouldNotBloatStarredColumns(double firstColumnWidth)
293
455
294
456
outerGrid . ColumnDefinitions . Add ( new ColumnDefinition ( ) { Width = new GridLength ( firstColumnWidth , GridUnitType . Star ) } ) ; // 0.3, but 0.2 works fine
295
457
outerGrid . ColumnDefinitions . Add ( new ColumnDefinition ( ) { Width = GridLength . Star } ) ;
296
-
297
- // This last column is the trouble spot; MeasureAndContractStarredColumns needs to account for this width
458
+
459
+ // This last column is the trouble spot; MeasureAndContractStarredColumns needs to account for this width
298
460
// when measuring and distributing the starred column space. Otherwise it reports the wrong width and every
299
461
// measure after that is wrong.
300
462
outerGrid . ColumnDefinitions . Add ( new ColumnDefinition ( ) { Width = 36 } ) ;
@@ -307,7 +469,7 @@ public void AbsoluteColumnShouldNotBloatStarredColumns(double firstColumnWidth)
307
469
innerGrid . RowDefinitions . Add ( new RowDefinition ( ) { Height = GridLength . Auto } ) ;
308
470
innerGrid . RowDefinitions . Add ( new RowDefinition ( ) { Height = GridLength . Auto } ) ;
309
471
310
- var hugeLabel = new _12292TestLabel ( ) { } ;
472
+ var hugeLabel = new _12292TestLabel ( ) { } ;
311
473
var tinyLabel = new ColumnTestLabel { Text = "label1" } ;
312
474
313
475
innerGrid . Children . Add ( hugeLabel ) ;
@@ -448,13 +610,15 @@ public FixedSizeLabel(Size minimumSize, Size requestedSize)
448
610
_requestedSize = requestedSize ;
449
611
}
450
612
613
+ public FixedSizeLabel ( Size size ) : this ( size , size ) { }
614
+
451
615
protected override SizeRequest OnMeasure ( double widthConstraint , double heightConstraint )
452
616
{
453
617
return new SizeRequest ( _requestedSize , _minimumSize ) ;
454
618
}
455
619
}
456
620
457
- class _12292TestLabel : Label
621
+ class _12292TestLabel : Label
458
622
{
459
623
// We need a label that simulates a fairly specific layout/measure pattern to reproduce
460
624
// the circumstances of issue 12292.
@@ -508,8 +672,8 @@ protected override SizeRequest OnMeasure(double widthConstraint, double heightCo
508
672
509
673
class HeightBasedOnTextLengthLabel : TestLabel
510
674
{
511
- public double DesiredHeight ( double widthConstraint )
512
- {
675
+ public double DesiredHeight ( double widthConstraint )
676
+ {
513
677
return ( Text . Length / widthConstraint ) * 200 ;
514
678
}
515
679
0 commit comments