WinUI 3中如何让Canvas控件支持滚动显示?
问题根因
Canvas 控件默认不会根据内部子元素的位置和尺寸自动调整自身的宽高,它的默认测量尺寸为0,因此外层的 ScrollViewer 无法感知到 Canvas 内部内容已经超出可视范围,自然不会触发滚动条显示。
解决方案1:手动设置Canvas尺寸
在所有子元素添加完成后,遍历所有子元素计算出Canvas需要的最小宽高,手动赋值给Canvas即可。
在你现有代码的for循环结束后添加如下逻辑:
// 计算所需的最大宽高 double maxWidth = 0; double maxHeight = 0; foreach (UIElement child in MainCanvas.Children) { double right = Canvas.GetLeft(child) + child.RenderSize.Width; double bottom = Canvas.GetTop(child) + child.RenderSize.Height; if (right > maxWidth) maxWidth = right; if (bottom > maxHeight) maxHeight = bottom; } // 给Canvas加一点内边距避免子元素贴边 MainCanvas.Width = maxWidth + 20; MainCanvas.Height = maxHeight + 20;
同时调整XAML中ScrollViewer的配置,明确开启滚动条:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <Canvas x:Name="MainCanvas"/> </ScrollViewer>
解决方案2:自定义自动适配内容的Canvas
如果需要频繁修改Canvas内的子元素,每次手动计算尺寸太繁琐,可以继承Canvas重写测量逻辑,让它自动适配子元素尺寸:
public class AutoSizeCanvas : Canvas { protected override Size MeasureOverride(Size constraint) { Size availableSize = new Size(double.PositiveInfinity, double.PositiveInfinity); double maxWidth = 0; double maxHeight = 0; foreach (UIElement child in InternalChildren) { child.Measure(availableSize); double right = GetLeft(child) + child.DesiredSize.Width; double bottom = GetTop(child) + child.DesiredSize.Height; if (right > maxWidth) maxWidth = right; if (bottom > maxHeight) maxHeight = bottom; } return new Size(maxWidth, maxHeight); } }
之后把XAML里的Canvas替换成这个自定义控件即可,不需要再手动设置宽高:
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <local:AutoSizeCanvas x:Name="MainCanvas"/> </ScrollViewer>
内容的提问来源于stack exchange,提问作者dotnetzen
相关产品推荐
相关产品推荐

