【问题标题】:Windows.Forms.Panel 32767 size limitWindows.Forms.Panel 32767 大小限制
【发布时间】:2020-09-19 09:51:13
【问题描述】:

我有一个使用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 大小后,不再显示图像。

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

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

【问题讨论】:

  • 32767 - 是Int16 类型的最大值,但Size.WidthSize.HeightInt32 类型,你说的是哪个尺寸?
  • @sll 我认为他的意思是 myPanel.Controls 不会超过 32k 项 - 呃...
  • Windows 本身将高度/宽度打包到一个 16 位 WORD 中,因此您在任一维度上都限制为 32767,您必须使用视口区域并仅显示需要可见的内容
  • @dave :但是 OP 说 height of the panel exceeds 32767 pixels

标签: c# .net winforms


【解决方案1】:

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

您必须以不同的方式执行此操作。就像在 Paint 方法中使用 Graphics.TranslateTransform()。

【讨论】:

    【解决方案2】:

    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 位整数表示的最大数。

    【讨论】:

    • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    【解决方案3】:

    没有绘制方法的解决方案

    我遇到了这个确切的问题。我不想重新编写已经编码到我的子控件中的功能。该例程通过滚动条管理子控件,并将不在播放中的控件隐藏起来并离开屏幕。

    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 构建控件以允许相同的应用程序+视图呈现为 Web 应用程序和 Windows 应用程序时,我分别传入了子项的边界。与将其限制为面板相同。根据需要重构。

    【讨论】:

      【解决方案4】:

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

      只需设置 AutoScrollbar = true

      只需将 RightToLeft 属性设置为 true。

      【讨论】:

        猜你喜欢
        • 2011-08-19
        • 1970-01-01
        • 2014-08-09
        • 1970-01-01
        • 2011-11-21
        • 2018-04-16
        • 2010-12-29
        • 2012-10-16
        相关资源
        最近更新 更多