.net - 更改 Canvas 内控件的位置后,滚动条不可见

标签 .net wpf canvas custom-controls scrollviewer

我创建了一个继承自 WPF Canvas 的自定义 Canvas 控件。我在主窗口中这样使用它-

<ScrollViewer
    HorizontalScrollBarVisibility="Auto"
    VerticalScrollBarVisibility="Auto">
    <RTD:RTDesignerCanvas
        Margin="5"
        Background="White"
        x:Name="canvas1"
        Focusable="True"
        AllowDrop="True">
    </RTD:RTDesignerCanvas>
</ScrollViewer>

一切正常,但是当我尝试像这样设置控件的位置时

Canvas.SetTop(item, 200);

滚动条不可见,控件隐藏在某处。有趣的是,如果我向它添加另一个控件,滚动条是可见的,我可以向下滚动以查看上一个控件。

我尝试使用

base.InvalidateVisual();
base.UpdateLayout();
base.InvalidateArrange();

在更改项目 TopLeft 但没有任何反应;是我遗漏了什么还是由于某些错误而发生这种情况?

更新:

澄清一下,假设我有一个 Canvas ,其 widthheight 为 100、100。现在,如果我使用 移动控件(已添加到 Canvas 中) >Canvas.SetLeft(myControl, 200) 然后它会移动到一个默认不可见的位置并且滚动条也被禁用,所以没有办法看到那个控件。

现在如果我向 Canvas 添加另一个控件,ScrollBars 会正确显示,并且我可以通过滚动看到之前的控件。

最佳答案

您是否覆盖了 MeasureOverride在您的自定义 Canvas 中? Canvas 将始终报告 (0, 0) 的 DesiredSize,因此 ScrollViewer 永远不会认为它需要滚动。

this StackOverflow answer这建议使用 Grid 而不是 Canvas 并使用 Margin 属性进行定位。 Grid 将根据其子项的大小和位置报告其大小,因此 ScrollViewer 将知道它需要滚动。

更新:

ScrollViewer 会根据它的要求给它的 child 询问多大的尺寸,并且只有当 child 比 ScrollViewer 大时才需要滚动。为了让它正确滚动,您需要报告一个足够大以包含所有子控件的 DesiredSize。您可以通过像这样覆盖 MeasureOverride 来做到这一点:

protected override Size MeasureOverride(Size constraint)
{
    base.MeasureOverride(constraint);
    var desiredSize = new Size();
    foreach (UIElement child in Children)
    {
        desiredSize = new Size(
            Math.Max(desiredSize.Width, GetLeft(child) + child.DesiredSize.Width),
            Math.Max(desiredSize.Height, GetTop(child) + child.DesiredSize.Height));
    }
    return desiredSize;
}

然而,一个更简单的解决方案是利用 Grid 类已经像这样进行测量的事实。您可以使用子元素的 Margin 属性来准确定位它们,而不是使用 Canvas.Left 和 Canvas.Top 属性。如果你目前正在做

Canvas.SetLeft(item, 100);
Canvas.SetTop(item, 200);

对于 Canvas 中的项目,您可以改为这样做

item.Margin = new Thickness(100, 200, 0, 0);

将其放置在单格网格内的相同位置。

关于.net - 更改 Canvas 内控件的位置后,滚动条不可见,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3061400/

相关文章:

c# - 使用 Active Directory 服务帐户从 .NET 连接到 SQL Server

.net - TFS 2015 构建模板无法构建 C#7 功能

.net - 创建将字符串转换为可为空的数字的通用方法

javascript - 背景图片翻译?

.net - .NET 堆的约 50% 的空闲对象。如何知道是什么导致了 OOM

wpf - WinForms 中的 anchor == WPF 中的水平(+垂直)对齐?

C# 当消息框处于事件状态时执行操作

c# - UserControl 上的 SizeToContent

javascript - Fabric js如何防止对象缩放到 Canvas 边界之外?

javascript - 用于图像裁剪的 Canvas - context.drawImage()