更改画布内控件的位置后,滚动条不可见
我创建了一个继承自 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();
我尝试在更改项目 Top
或 Left
后 ,但没有任何反应;我是否遗漏了什么或由于某些错误而发生这种情况?
更新:
澄清一下,假设我有一个画布,其宽度
、高度
分别为100、100。现在,如果我移动一个控件(已添加在画布中)使用 Canvas.SetLeft(myControl, 200)
然后它将移动到默认情况下不可见的位置,并且滚动条也被禁用,因此无法看到该控件。
现在,如果我向 Canvas 添加另一个控件,ScrollBars 会正确显示,并且我可以通过滚动看到前一个控件。
I created a custom canvas control inheriting from WPF Canvas
. I am using it like this in main window -
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<RTD:RTDesignerCanvas
Margin="5"
Background="White"
x:Name="canvas1"
Focusable="True"
AllowDrop="True">
</RTD:RTDesignerCanvas>
</ScrollViewer>
Everything works fine but when I try to set the position of controls inside it like this
Canvas.SetTop(item, 200);
scrollbars are not visible and control is hidden down somewhere. Interestingly, if I add another control to it scroll bars are visible and I can scroll downwards to see the previous control.
I tried to use
base.InvalidateVisual();
base.UpdateLayout();
base.InvalidateArrange();
after changing items Top
or Left
but nothing happens; Am I missing something or this happens due to some bug?
Update:
to clarify, say I have a canvas having its width
, height
as 100, 100. Now if I move a control(already added in canvas) using Canvas.SetLeft(myControl, 200)
then it will move to a position which is not visible by default and scroll bars are also disabled, so there is no way to see that control.
Now if I add another control to Canvas, ScrollBars appear correctly and I can see the previous control by scrolling.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否在自定义画布中覆盖了 MeasureOverride ? Canvas 将始终报告 DesiredSize 为 (0, 0),因此 ScrollViewer 永远不会认为它需要滚动。
请参阅此 StackOverflow 答案,其中建议使用网格画布并使用 Margin 属性进行定位。 Grid 将根据其子级的大小和位置报告其大小,因此 ScrollViewer 将知道它需要滚动。
更新:
ScrollViewer 将为其子级提供所需的大小,并且仅当子级大于 ScrollViewer 时才需要滚动。为了让它正确滚动,您需要报告一个足够大的 DesiredSize 以包含所有子控件。您可以通过重写 MeasureOverride 来实现这一点,如下所示:
然而,一个更简单的解决方案是利用 Grid 类已经像这样进行测量的事实。您可以使用子元素的 Margin 属性来精确定位它们,而不是使用 Canvas.Left 和 Canvas.Top 属性。如果您当前正在
画布中处理某个项目,则可以将
其放置在单单元格网格中的同一位置。
Did you override MeasureOverride in your custom Canvas? Canvas will always report a DesiredSize of (0, 0), so the ScrollViewer will never think it needs to scroll.
See this StackOverflow answer which suggests using a Grid instead of a Canvas and using the Margin property for positioning. The Grid will report its size based on the size and position of its children, so the ScrollViewer will know it needs to scroll.
Update:
ScrollViewer will give its child ask much size as it asks for, and will only need to scroll if the child is larger than the ScrollViewer. In order to have it scroll properly, you'll need to report a DesiredSize that is large enough to include all of your child controls. You can do that by overriding MeasureOverride like this:
An easier solution, however, is to take advantage of the fact that the Grid class will already measure like this. You can use the Margin property of the child elements to position them exactly instead of the Canvas.Left and Canvas.Top properties. If you are currently doing
for an item in the Canvas, you could instead do
to position it in the same place within a one-cell Grid.
Quartermeister的回答帮助我解决了这个问题。
我必须在每次操作后显式使用
base.InvalidateMeasure()
来刷新画布并使滚动条可见。Quartermeister's answer helped me in solving this issue.
I had to use
base.InvalidateMeasure()
explicitly after each operation to refresh the canvas and make the scrollbars visible.Akjoshi,
这一定是一个错误。下次画布隐藏在某个地方时,对其运行 Snoop 并检查它在哪里。确保检查以下画布属性:
ActualWidth
、ActualHeight
、Opacity
、Visibility
Akjoshi,
It has to be a bug. Next time the canvas becomes somewhere hidden, run Snoop on it, and check where it is. Makes sure to check the following canvas properties:
ActualWidth
,ActualHeight
,Opacity
,Visibility