Xamarin Forms如何可靠获取控件的实际宽高尺寸?
Xamarin Forms 可靠获取控件尺寸的解决方案
问题根因
你获取到的宽高为-1、Bounds值不稳定,本质是读取时机早于Xamarin Forms布局流程完成阶段。Xamarin Forms控件渲染会先后经过Measure测量、Arrange排列两个阶段,只有两个阶段全部执行完成,控件的Width、Height、Bounds属性才会被赋予真实渲染后的有效值,未完成布局时这些属性的默认值为-1,代表未被赋值。
你示例中AbsoluteLayout的Button只设置了LayoutBounds的坐标值,未显式设置宽高时,控件会根据文字、字号等内容自适应尺寸,自适应的尺寸也需要布局完成后才能读取到。
可用解决方案
方案1:监听SizeChanged事件(最可靠,优先使用)
控件完成布局、尺寸最终确定后会触发SizeChanged事件,在此事件回调中读取的尺寸为真实渲染值:
// 单次执行写法,触发后自动解绑事件避免重复调用 btn.SizeChanged += (sender, args) => { btn.SizeChanged -= (s,e) => { }; var realWidth = btn.Width; var realHeight = btn.Height; var realBounds = btn.Bounds; // 后续业务逻辑 };
方案2:调度到UI队列等待布局完成后读取
如果需要在页面加载逻辑中一次性读取,可以把读取逻辑调度到UI线程队列尾部,等布局流程完成后再执行:
// 在页面或控件的上下文中调用 Dispatcher.Dispatch(() => { var realWidth = btn.Width; var realHeight = btn.Height; });
方案3:主动测量获取预估尺寸
如果需要在布局完成前提前获取控件的预估尺寸,可以主动调用测量方法获取控件的理想尺寸:
// 传入父布局的可用宽高限制,无特殊限制的话传入double.PositiveInfinity ctrl.Measure(double.PositiveInfinity, double.PositiveInfinity); // 获取测量后的预估尺寸 var desiredWidth = ctrl.DesiredSize.Width; var desiredHeight = ctrl.DesiredSize.Height;
注意:该方法得到的是不受父布局约束的理想尺寸,和最终实际渲染尺寸可能存在差异,仅适合无父布局限制的场景使用。
内容的提问来源于stack exchange,提问作者Adam Jachocki
相关产品推荐
相关产品推荐

