|
| 1 | +# Variable Height Testing Setup |
| 2 | + |
| 3 | +## Changes Made to ComplexVirtualizationPage |
| 4 | + |
| 5 | +### Modified Files: |
| 6 | +1. `samples/ControlCatalog/ViewModels/ComplexVirtualizationPageViewModel.cs` |
| 7 | + |
| 8 | +### What Was Changed: |
| 9 | + |
| 10 | +#### 1. Enhanced SampleText Array (Line 162-179) |
| 11 | +Added 15 text samples with **extreme length variance**: |
| 12 | +- **Very short**: "A", "Brief.", "Short text." (1-10 characters) |
| 13 | +- **Short**: Single sentences (~50-60 characters) |
| 14 | +- **Medium**: Standard Lorem Ipsum sentences (~100-120 characters) |
| 15 | +- **Long**: Extended Lorem Ipsum paragraphs (~200-250 characters) |
| 16 | +- **Very long**: Excessive verbose sentence (~300+ characters) |
| 17 | + |
| 18 | +This creates text that will wrap from 0 lines to 5+ lines depending on container width. |
| 19 | + |
| 20 | +#### 2. Person Bio Length (Lines 33-43) |
| 21 | +**Old**: 0-4 sentences |
| 22 | +**New**: Weighted distribution 0-11 sentences: |
| 23 | +- 9% - No bio (0 sentences) |
| 24 | +- 18% - Very short (1 sentence, ~1 line) |
| 25 | +- 27% - Short (2-3 sentences, ~2-3 lines) |
| 26 | +- 18% - Medium (4-5 sentences, ~3-4 lines) |
| 27 | +- 18% - Long (6-8 sentences, ~5-7 lines) |
| 28 | +- 9% - Very long (9-11 sentences, ~8-10 lines) |
| 29 | + |
| 30 | +**Skills**: Increased from 2-7 to 2-10 skills |
| 31 | + |
| 32 | +#### 3. Task Description Length (Lines 69-78) |
| 33 | +**Old**: 1-5 sentences |
| 34 | +**New**: Weighted distribution 1-12 sentences: |
| 35 | +- 18% - Very short (1 sentence) |
| 36 | +- 27% - Short (2-3 sentences) |
| 37 | +- 27% - Medium (4-6 sentences) |
| 38 | +- 18% - Long (7-9 sentences) |
| 39 | +- 9% - Very long (10-12 sentences) |
| 40 | + |
| 41 | +**Subtasks**: Increased from 2-6 to 2-8 subtasks |
| 42 | + |
| 43 | +#### 4. Product Description Length (Lines 110-119) |
| 44 | +**Old**: 0-3 sentences (50% chance) |
| 45 | +**New**: Weighted distribution 0-8 sentences: |
| 46 | +- 11% - No description |
| 47 | +- 22% - Very short (1 sentence) |
| 48 | +- 22% - Short (2-3 sentences) |
| 49 | +- 22% - Medium (4-5 sentences) |
| 50 | +- 22% - Long (6-8 sentences) |
| 51 | + |
| 52 | +**Tags**: Increased from 1-10 to 1-12 tags |
| 53 | + |
| 54 | +#### 5. Photo Caption Length (Lines 135-144) |
| 55 | +**Old**: 0-4 sentences |
| 56 | +**New**: Weighted distribution 0-8 sentences: |
| 57 | +- 11% - No caption |
| 58 | +- 22% - Very short (1 sentence) |
| 59 | +- 22% - Short (2-3 sentences) |
| 60 | +- 22% - Medium (4-5 sentences) |
| 61 | +- 22% - Long (6-8 sentences) |
| 62 | + |
| 63 | +**Comments**: Increased from 1-5 to 1-7 comments |
| 64 | + |
| 65 | +--- |
| 66 | + |
| 67 | +## Expected Item Height Variance |
| 68 | + |
| 69 | +With these changes, item heights will vary **dramatically**: |
| 70 | + |
| 71 | +### Minimum Heights (No text content): |
| 72 | +- **PersonItem**: ~150px (header + name/email + phone only) |
| 73 | +- **TaskItem**: ~120px (header + title + progress bar only) |
| 74 | +- **ProductItem**: ~100px (header + name + price only) |
| 75 | +- **PhotoItem**: ~120px (image + header + title + location only) |
| 76 | + |
| 77 | +### Maximum Heights (Full text content): |
| 78 | +- **PersonItem**: ~800px+ (long bio + 10 skills) |
| 79 | +- **TaskItem**: ~900px+ (very long description + 8 subtasks) |
| 80 | +- **ProductItem**: ~600px+ (long description + 12 tags) |
| 81 | +- **PhotoItem**: ~700px+ (long caption + 7 comments) |
| 82 | + |
| 83 | +### Height Ratio: |
| 84 | +- **Minimum to Maximum**: ~5:1 to 8:1 ratio |
| 85 | +- **Average height variance**: Items will randomly range from 100px to 900px |
| 86 | + |
| 87 | +--- |
| 88 | + |
| 89 | +## How to Test |
| 90 | + |
| 91 | +### 1. Enable Tracing (Optional) |
| 92 | +In your XAML or code, enable tracing on the VirtualizingStackPanel: |
| 93 | +```csharp |
| 94 | +var stackPanel = listBox.ItemsPanelRoot as VirtualizingStackPanel; |
| 95 | +if (stackPanel != null) |
| 96 | +{ |
| 97 | + stackPanel.IsTracingEnabled = true; |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +### 2. Run the ControlCatalog Sample |
| 102 | +```bash |
| 103 | +cd samples/ControlCatalog |
| 104 | +dotnet run |
| 105 | +``` |
| 106 | + |
| 107 | +### 3. Navigate to ComplexVirtualizationPage |
| 108 | +In the ControlCatalog, find and click on "Content Virtualization Demo" |
| 109 | + |
| 110 | +### 4. Observe Scrolling Behavior |
| 111 | + |
| 112 | +**What to look for:** |
| 113 | + |
| 114 | +#### ✅ Good Behavior (Distance-based gap tolerance working): |
| 115 | +- Smooth scrolling up and down |
| 116 | +- No "RECYCLING ALL" messages during normal scrolling |
| 117 | +- Debug output shows gaps like: |
| 118 | + ``` |
| 119 | + GapBefore=5 items (650px/605px), Disjunct=False |
| 120 | + GapBefore=8 items (1040px/605px), Disjunct=True → RECYCLING (expected for large gap) |
| 121 | + ``` |
| 122 | +- Items vary wildly in height, but scrolling remains smooth |
| 123 | + |
| 124 | +#### ❌ Bad Behavior (If distance-based tolerance wasn't working): |
| 125 | +- Frequent "RECYCLING ALL" messages |
| 126 | +- Stuttering/janky scrolling |
| 127 | +- Gap calculations ignoring actual pixel distances: |
| 128 | + ``` |
| 129 | + GapBefore=5 items (5000px/605px), Disjunct=False → BAD! Should recycle |
| 130 | + ``` |
| 131 | + |
| 132 | +### 5. Test Scenarios |
| 133 | + |
| 134 | +#### Scenario A: Slow Smooth Scrolling |
| 135 | +- Scroll slowly from top to bottom |
| 136 | +- Expected: No recycling, all gaps handled incrementally |
| 137 | +- Debug shows: `GapBefore/After` values staying below thresholds |
| 138 | + |
| 139 | +#### Scenario B: Fast Scrolling |
| 140 | +- Rapidly scroll down/up |
| 141 | +- Expected: Occasional recycling when gaps exceed viewport size |
| 142 | +- Debug shows: `Disjunct=True` only when gap distance > 605px |
| 143 | + |
| 144 | +#### Scenario C: Jump to End |
| 145 | +- Scroll all the way to bottom quickly |
| 146 | +- Expected: One "RECYCLING ALL" as viewport jumps far |
| 147 | +- Debug shows: Large gap distance triggering disjunct |
| 148 | + |
| 149 | +#### Scenario D: Scroll Up from End |
| 150 | +- At bottom, scroll slowly upward |
| 151 | +- Expected: No recycling until gap exceeds 605px (100% of viewport) |
| 152 | +- This was the original issue - now fixed! |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +## Debug Output Example |
| 157 | + |
| 158 | +With tracing enabled, you should see output like: |
| 159 | + |
| 160 | +``` |
| 161 | +[VSP] CalculateMeasureViewport: Anchor=15 (u=2340.50), Realized=[10-30] (Count=21), |
| 162 | + GapBefore=5 items (650px/605px), GapAfter=-15 items (-1950px/302px), |
| 163 | + Disjunct=True, ViewportSize=605px |
| 164 | +[VSP] RECYCLING ALL - HasReachedEnd=False, HasReachedStart=False, ItemCount=5000 |
| 165 | +
|
| 166 | +[VSP] CalculateMeasureViewport: Anchor=42 (u=6500.00), Realized=[40-58] (Count=19), |
| 167 | + GapBefore=2 items (260px/605px), GapAfter=-16 items (-2080px/302px), |
| 168 | + Disjunct=False, ViewportSize=605px |
| 169 | +``` |
| 170 | + |
| 171 | +**Key metrics to watch:** |
| 172 | +- **Gap pixel distance**: Should accurately reflect estimated height × item count |
| 173 | +- **Disjunct decision**: Should be `True` only when pixel distance exceeds thresholds |
| 174 | +- **ViewportSize**: Should match your window's visible area |
| 175 | + |
| 176 | +--- |
| 177 | + |
| 178 | +## Verification Checklist |
| 179 | + |
| 180 | +- [ ] Items have wildly varying heights (100px to 900px range) |
| 181 | +- [ ] Text wraps across multiple lines in many items |
| 182 | +- [ ] Scrolling is smooth without excessive recycling |
| 183 | +- [ ] "RECYCLING ALL" only appears on large jumps |
| 184 | +- [ ] Debug output shows pixel-based gap calculations |
| 185 | +- [ ] Backward scrolling (up) tolerates larger gaps than forward scrolling |
| 186 | +- [ ] No layout cycle warnings during normal scrolling |
| 187 | + |
| 188 | +--- |
| 189 | + |
| 190 | +## Performance Comparison |
| 191 | + |
| 192 | +### Before Distance-Based Tolerance: |
| 193 | +- Fixed 2-item gap tolerance |
| 194 | +- Small items: Frequent unnecessary recycling (e.g., 5 tiny items = 100px, incorrectly recycled) |
| 195 | +- Large items: Inadequate recycling (e.g., 3 huge items = 2700px, incorrectly kept) |
| 196 | + |
| 197 | +### After Distance-Based Tolerance: |
| 198 | +- Dynamic tolerance based on viewport size |
| 199 | +- Small items: Many items can be realized without recycling (gap < 605px) |
| 200 | +- Large items: Fewer items trigger recycling (gap > 605px) |
| 201 | +- Adaptive: Works perfectly regardless of item size distribution |
0 commit comments