Windows.Forms.Panel 32767大小限制

我有一个使用Windows.Forms.Panel显示图片列表的应用程序。 当面板的高度超过32767像素时,其余内容将被简单地切掉。

例:

 Windows.Forms.Panel myPanel; ArrayList pictureList; foreach(pic in pictureList) { myPanel.Controls.Add(pic) // adds all the objects without complaints } 

在示例中,所有元素都添加到面板而不会引发错误,但是在面板达到32767之后,不再显示任何图像。

我的问题:是否有可能打破此限制并在面板中显示更多内容?

我知道这种方法无论如何都不方便,但现在没有时间重新设计整个应用程序了。

这是Windows中的架构限制。 指示窗口中位置的各种消息,如WM_MOUSEMOVE,以32位整数报告位置,X位为16位,Y位为16位。 因此,您无法创建大于short.MaxValue的窗口。 这不是一个真正的问题,没有人有一个超过32,767像素的显示器,并且很长一段时间都没有。

你必须以不同的方式做到这一点。 就像在Paint方法中使用Graphics.TranslateTransform()一样。

LPARAM – 用于将消息参数传递给Windows过程的Windows数据类型。 它是一个32位指针,它将消息作为两部分传递,即以高位(32位的前16位)和低位(32位的第二位16位)。

  Where High order is used to pass the height of the control and Low order is used to pass the width of the control 

因此,如果控件的高度或宽度超过32762size,则显示错误,因为

32767是可以在带符号的16位整数中表示的最大数字。

没有油漆方法的解决方案

我遇到了这个问题。 我不想重写已经编码到我的子控件中的function。 此例程通过滚动条管理子控件,并使隐藏的场外控件保持隐藏状态。

 Public Class ManuallyScrollingPanel Inherits Panel Public WithEvents sbar As New System.Windows.Forms.VScrollBar Sub New() MyBase.New() Controls.Add(sbar) sbar.Visible = True Me.AutoScroll = False End Sub Sub SetScrollParams() If PanelPositions.Any Then Dim NewMax = CInt((From item In PanelPositions.Values Select item.Bottom).Max + 500) - Height If sbar.Maximum <> NewMax Then sbar.Maximum = NewMax End If End If End Sub Public Sub RegisterChildSize(pnl As Panel, DesiredBounds As Drawing.Rectangle) PanelPositions(pnl) = DesiredBounds SetScrollParams() End Sub Dim PanelPositions As New Dictionary(Of Panel, Drawing.Rectangle) Private Sub ManuallyScrollingPanel_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged sbar.Top = 0 sbar.Left = Width - sbar.Width sbar.Height = Me.Height SetScrollParams() sbar.LargeChange = CInt(Height * 0.9) sbar.SmallChange = CInt(Height * 0.2) End Sub Private Sub sb_Scroll(sender As Object, e As ScrollEventArgs) Handles sbar.Scroll ScrollTo(e.NewValue) End Sub Private Sub sb_ValueChanged(sender As Object, e As EventArgs) Handles sbar.ValueChanged ScrollTo(sbar.Value) End Sub Sub ScrollTo(pos As Integer) Me.AutoScroll = False For Each kvp In PanelPositions Dim VirtBounds = New Drawing.Rectangle(CInt(kvp.Value.Left), CInt(kvp.Value.Top - pos), CInt(kvp.Value.Width), CInt(kvp.Value.Height)) If VirtBounds.Bottom < 0 Or VirtBounds.Top > Height Then ' it's not visible - hide it and position offscreen kvp.Key.Visible = False kvp.Key.Top = VirtBounds.Top Else ' Visible, position it kvp.Key.Top = VirtBounds.Top kvp.Key.Visible = True End If Next End Sub End Class 

然后,对于每个子控件(我的动态添加,听起来像OP正在做同样的事情)进行此调用:

 CType(Parent, ManuallyScrollingPanel).RegisterChildSize(Me, PanelObject.Bounds) 

注意我从DTO构建控件时分别传入子区域,以允许相同的app +视图呈现为Web应用程序和Windows应用程序。 与限制面板相同。 根据需要重构。

为什么不在面板中添加滚动条

只需设置AutoScrollbar = true

并将RightToLeft属性设置为true。