Ограничение размера Windows.Forms.Panel 32767 - PullRequest
6 голосов
/ 09 ноября 2011

У меня есть приложение, которое использует 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, изображение больше не отображается.

Мой вопрос: возможно ли нарушить этот предел и отобразить больше содержимого на панели?

IЯ знаю, что такой подход неудобен в любом случае, но сейчас нет времени на перепроектирование всего Приложения.

Ответы [ 4 ]

11 голосов
/ 09 ноября 2011

Это архитектурное ограничение в Windows.Различные сообщения, которые указывают позиции в окне, такие как WM_MOUSEMOVE, сообщают о положении в 32-разрядном целом числе с 16-разрядными для X и 16-разрядными для Y-позиции.Поэтому вы не можете создать окно, которое больше, чем short.MaxValue.Это не совсем реальная проблема, ни у кого нет монитора, который шире, чем 32 767 пикселей, и не надолго.

Вам придется делать это по-другому.Как использование Graphics.TranslateTransform () в методе Paint.

1 голос
/ 26 октября 2015

Решение без покраски

У меня была именно эта проблема.Я не хотел переписывать функциональность, которая уже была закодирована в моих дочерних элементах управления.Эта подпрограмма управляет дочерними элементами управления с помощью полосы прокрутки и сохраняет скрытые и незадействованные элементы вне игры.

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, чтобы те же приложения + представления отображались как веб-приложение и приложение для Windows,То же самое с ограничением на панели.Рефакторинг при необходимости.

1 голос
/ 05 декабря 2013

LPARAM - Тип данных Windows, используемый для передачи параметров сообщения в процедуру Windows.Это 32-битный указатель, который передает сообщение в виде двух частей, то есть в верхнем порядке (первые 16 битов по 32 бита) и низком порядке (вторые 16 битов по 32 бита).ширина элемента управления превышает 32762, он показывает ошибку, потому что

32767 - это наибольшее число, которое может быть представлено в 16-разрядном целом числе со знаком.

0 голосов
/ 09 ноября 2011

Почему бы вам не добавить полосу прокрутки на панель

просто установите AutoScrollbar = true

и просто установите для свойства RightToLeft значение true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...