HandyControl
HandyControl copied to clipboard
fix:Row错误行数、高度导致响应式布局不生效,具体表现为第一次渲染时容器高度计算错误,鼠标移入控件时触发布局更新,高度才正常
失败原因:
- Row 在第一次 Measure 时用到了错误的布局状态(_layoutStatus=null)并且父宽度为 Infinity,导致计算出错误的高度。
- 时序图: 父容器 (StackPanel) ↓ 调用 Row.Measure(constraint) constraint.Width = Infinity ❌ | ├─ 未设置 _layoutStatus (为 null) ├─ 子控件 Measure() 用错误的列数计算宽度 ├─ Row 返回过大的 Height (假设两倍) ↓ Row.Arrange(finalSize) ├─ 这里才设置 _layoutStatus ✅ ├─ 但高度已被父容器缓存,未重新计算 ❌ ↓ 渲染结果:首帧高度过高 → 出现多余空白
鼠标移入(触发布局刷新) ↓ 重新执行 Measure/Arrange constraint.Width 已确定 _layoutStatus 正确 ↓ 高度恢复正常 ✅
修复方法:
- 通过「独立计算 layoutStatus + 检测 Infinity + 监听父尺寸变化」三步,确保第一次布局就有正确的约束和测量结果,从根本上消除了空白闪动问题。
- 时序图: 父容器 (StackPanel) ↓ 调用 Row.Measure(constraint) constraint.Width = Infinity | ├─ 检测到 Infinity → 用 parent.ActualWidth 替代 ✅ ├─ 即使父未渲染,也安排 Dispatcher.BeginInvoke(InvalidateMeasure) 延迟重测 ✅ ├─ 当宽度可用时,localLayoutStatus = ColLayout.GetLayoutStatus(width) ✅ ├─ 子控件正确测量,Row 得出准确高度 ✅ ↓ Row.Arrange(finalSize) ├─ 使用同样 layoutStatus ├─ 正常布局所有列 ✅ ↓ 首帧渲染就正确无空白 ✅
@y60024651 看了下,感觉只要再 MeasureOverride 方法开头加一行 _layoutStatus = ColLayout.GetLayoutStatus(constraint.Width); 就能解决了,你确认下呢?