Viewbox嵌套Canvas,运行时无法通过ActualWidth/ActualHeight获取真实尺寸
解决Viewbox内Canvas真实宽高获取问题
问题核心是Viewbox对Canvas的缩放是通过渲染变换(RenderTransform)实现的,而Canvas的ActualWidth/ActualHeight只会返回你设置的固定值,不会自动计算缩放后的尺寸。要拿到真实显示的宽高,有两种常用方法:
方法1:计算缩放因子后换算
Viewbox内部会维护一个缩放比例,你可以通过Viewbox.ActualWidth和它的子元素(外层Canvas)的原始宽度算出缩放比例,再用这个比例乘以内部Canvas的尺寸:
修改后台代码如下:
private void Button_Click(object sender, RoutedEventArgs e) { // 获取外层Viewbox var viewbox = innerCanvas.Parent.Parent as Viewbox; if (viewbox == null) return; // 获取外层Canvas的原始尺寸 var outerCanvas = viewbox.Child as Canvas; if (outerCanvas == null) return; // 计算缩放比例(Viewbox会保持宽高比,取最小的那个比例) double scaleX = viewbox.ActualWidth / outerCanvas.Width; double scaleY = viewbox.ActualHeight / outerCanvas.Height; double scale = Math.Min(scaleX, scaleY); // 计算内部Canvas的真实显示尺寸 double realWidth = innerCanvas.Width * scale; double realHeight = innerCanvas.Height * scale; MessageBox.Show($"真实宽: {realWidth:F2}, 真实高: {realHeight:F2}"); }
方法2:改用LayoutTransform实现缩放(场景允许时)
如果你的布局可以调整,把Viewbox换成给外层Canvas添加LayoutTransform的方式,这样Canvas的ActualWidth/ActualHeight会直接反映缩放后的尺寸:
修改XAML:
<Window ... Title="MainWindow" Height="450" Width="800" SizeChanged="Window_SizeChanged"> <Grid> <Canvas Width="500" Height="300" Background="Red"> <Canvas.LayoutTransform> <ScaleTransform x:Name="canvasScale"/> </Canvas.LayoutTransform> <Canvas Width="200" Height="200" Background="Green" Name="innerCanvas"> </Canvas> </Canvas> <Button Click="Button_Click" Height="30" VerticalAlignment="Bottom" Content="Click"></Button> </Grid> </Window>
添加窗口尺寸变化事件和按钮点击事件代码:
private void Window_SizeChanged(object sender, SizeChangedEventArgs e) { var outerCanvas = innerCanvas.Parent as Canvas; if (outerCanvas == null) return; double scaleX = e.NewSize.Width / outerCanvas.Width; double scaleY = e.NewSize.Height / outerCanvas.Height; double scale = Math.Min(scaleX, scaleY); canvasScale.ScaleX = scale; canvasScale.ScaleY = scale; } private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show($"真实宽: {innerCanvas.ActualWidth:F2}, 真实高: {innerCanvas.ActualHeight:F2}"); }
内容的提问来源于stack exchange,提问作者Nehorai Raphael Elbaz
相关产品推荐
相关产品推荐

