更改“画布”内控件的位置后,ScrollBars不可见

时间:2010-06-17 11:56:52

标签: .net wpf canvas custom-controls scrollviewer

我创建了一个继承自WPF 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

但没有任何反应;我错过了什么或者由于某些错误而发生这种情况?

更新

澄清一下,说我有一个画布,其widthheight为100,100。现在如果我使用Canvas.SetLeft(myControl, 200)移动一个控件(已在画布中添加),那么它将会移动到默认情况下不可见的位置,滚动条也被禁用,因此无法看到该控件。

现在,如果我向Canvas添加另一个控件,ScrollBars会正确显示,我可以通过滚动来查看上一个控件。

3 个答案:

答案 0 :(得分:7)

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

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

更新:

ScrollViewer会根据需要给孩子多大的要求,如果孩子比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);

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

答案 1 :(得分:1)

Quartermeister的回答帮助我解决了这个问题。

我必须在每次操作后显式使用 base.InvalidateMeasure() 来刷新画布并使滚动条可见。

答案 2 :(得分:0)

Akjoshi,

它必须是一个错误。下次画布隐藏在某处时,在其上运行Snoop,并检查它的位置。确保检查以下画布属性:ActualWidthActualHeightOpacityVisibility