WPF ListView绑定ItemsSource后调用Measure/Arrange返回尺寸为0问题
问题根因
WPF的绑定更新、数据模板生成操作默认以DispatcherPriority.DataBind优先级加入UI线程调度队列,你同步调用Measure/Arrange时,绑定更新任务还未被调度执行,ListView的Items集合尚未填充,因此测量尺寸为0。你之前尝试直接调用绑定表达式的UpdateTarget无效,是因为此时属性变更通知还未被调度到绑定系统,调用时机过早。
可行解决方案
方案1:强制调度器先完成所有绑定相关任务
在执行测量前,先让Dispatcher处理完所有优先级大于等于DataBind的排队任务,确保绑定完全生效后再计算尺寸,修改你的GetMeasuredSize方法即可:
using System.Windows.Threading; public Size GetMeasuredSize(UserControl control) { // 强制处理所有DataBind及更高优先级的排队任务,等待绑定完成 control.Dispatcher.Invoke(DispatcherPriority.DataBind, new Action(() => { })); // 修正原代码的Arrange拼写错误 control.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); control.Arrange(new Rect(control.DesiredSize)); control.UpdateLayout(); return new Size(control.ActualWidth, control.ActualHeight); }
方案2:补充绑定触发必要条件
如果方案1未生效,检查以下基础配置:
ViewModel需实现INotifyPropertyChanged接口,Items属性赋值时触发PropertyChanged事件,确保绑定能感知属性变更- 若
Items集合在运行时会动态增减元素,将IEnumerable<MyItem>替换为ObservableCollection<MyItem>,触发集合变更通知
方案3:分页场景多次测量适配
如果是分页场景需要多次测量不同行数的尺寸,每次修改ViewModel的Items集合后,都调用一次上述Dispatcher空委托等待绑定完成,再执行测量即可。
内容的提问来源于stack exchange,提问作者Andy Stagg
相关产品推荐
相关产品推荐

