Подтвердить что ты не робот

Как предотвратить вертикальную полосу прокрутки от пробела в элементе управления, вызывая горизонтальную полосу прокрутки?

У меня есть настраиваемый элемент управления с встроенным FlowLayoutPanel, к которому я добавляю элементы (другие настраиваемые элементы управления). В событии компоновки FlowLayoutPanel меняю размеры всех элементов управления в FlowLayoutPanel на размер содержащего FlowLayoutPanel.

Это нормально, пока не потребуется вертикальная полоса прокрутки (AutoScroll = True), занимая пространство внутри FLpanel, вызывая горизонтальную полосу прокрутки.

Таблетка, которую вы видите, представляет собой случайный текст заполнителя, который я генерирую в конструкторе элемента.

Я хотел бы предотвратить это:

nasty scrollbar effect

Я попытался добавить вертикальный элемент управления прокруткой в ​​usercontrol и сделать FlowLayoutPanel.VertScroll.Value=sender.value в событии Scroll: он работает, но делает фактические вертикальные и горизонтальные полосы прокрутки мерцающими (появляющимися и исчезающими) при перемещении полосы прокрутки контроль.

Я действительно не знаю, есть ли какое-то свойство, чтобы сделать панель прокрутки внешней по отношению к содержимому элемента управления FlowLayoutPanel.

Я делаю это в VB.Net, но ответы на С# прекрасны (поскольку это в основном тот же синтаксис, по крайней мере, при работе с элементами управления и пользовательским интерфейсом).

Изменить


Я забыл упомянуть, что у меня есть WrapContents=false и AutoScroll=true в FlowLayoutPanel.

Кроме того, если вы считаете, что этот дизайн знаком: это идеальная копия экрана списка Opera M2, идеально подходящая для пикселя.

Обновление 1


После ваших комментариев я придумал следующее:

Public Class FlowListPanel ' The user control

Private Sub Me_Load(sender As Object, e As EventArgs) Handles Me.Load
    FL_Panel.AutoScroll = True ' FL_Panel is the FlowLayoutPanel
    FL_Panel.WrapContents = False

    FL_Panel.Dock = System.Windows.Forms.DockStyle.Fill
    FL_Panel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown
    FL_Panel.Margin = New System.Windows.Forms.Padding(0)
End Sub

Sub AddItem(c As Control)
    FL_Panel.Controls.Add(c)
    ReorderControls()
End Sub

Private Sub FLP_CSC(sender As Object, e As EventArgs) Handles FL_Panel.ClientSizeChanged
    ReorderControls()
End Sub

Sub ReorderControls()
    For Each ctrl In FL_Panel.Controls
        ctrl.Width = FL_Panel.ClientSize.Width
    Next
End Sub

Private Sub FL_Panel_L(sender As Object, e As LayoutEventArgs) Handles FL_Panel.Layout
    ReorderControls()
End Sub

End Class

Кажется, что это работает, но возникает проблема с появлением горизонтальной полосы прокрутки, когда достигается критическая точка, в которой появляется вертикальная полоса прокрутки.

После добавления другого элемента горизонтальная полоса прокрутки исчезает.

Кроме того, я думал, что проблема может быть вызвана тем, что ReorderControls не вызван, поэтому я сделал кнопку, чтобы вызвать его, но ничего не изменилось.

Эта проблема отсутствует при удалении элементов (но это происходит только при добавлении).

Это также происходит при изменении размера окна и появлении вертикальной полосы прокрутки.

Как я покажу ниже, после добавления нового элемента он отлично работает:

nasty scrollbar effect returns

Обновление 2


Я следил за советом Plutonix (адаптировав код из своего другого ответа), и поэтому я применил некоторые изменения к sub ReorderControls следующим образом:

    Sub ReorderControls()

    Dim HScrollVis As Boolean = NativeMethods.IsHScrollVisible(FL_Panel)

    If HScrollVis Then ' HScroll visible -> kill it with fire!
        NativeMethods.ShowHideScrollBar(FL_Panel,
                                        NativeMethods.SBOrientation.SB_HORZ,
                                        False)
        Return ' as it works anyway...
    End If

    For Each ctrl In FL_Panel.Controls
        ctrl.Width = FL_Panel.ClientSize.Width
    Next
    End Sub

Теперь горизонтальная полоса прокрутки мерцает один раз, а не остается там, когда появляется вертикальная.

Мне нравятся gif, так что вот текущий эффект:

nasty scrollbar effect: a new hope

Как вы, вероятно, не видите (из-за низкой частоты кадров в gif), горизонтальная панель, вероятно, заметна только для тех, кто ищет ее, в течение секунды.

Я считаю, что проблема 80% решена и будет двигаться дальше. Если я или кто-то придумаю что-то окончательное, я немедленно приму ответ.

4b9b3361

Ответ 1

Вот альтернативный подход, который дает вам желаемый результат. Если он не отвечает напрямую на ваш вопрос, но, на мой взгляд, если вам нужно возиться с тем, как работают элементы управления, чтобы получить желаемое решение, вы не используете правильные элементы управления.

Вместо того, чтобы добавлять свои элементы управления непосредственно в FowLayoutPanel,

Использовать стандартный объект Panel, содержащий таблицу TableLayoutPanel.

Задайте свойства панели...

AutoScroll = True

Задайте свойства TableLayoutPanel для

Dock = Top

Autosize = True, GrowAndSHrink

Начните с одной ячейки в TableLayoutPanel..

Теперь добавьте элементы управления в TableLayoutPanel...

например.

Dim CTRL As New Your_User_Control
TableLayoutPanel1.Controls.Add(CTRL)
CTRL.Dock = DockStyle.Top

Когда появится полоса прокрутки, TableLAyoutPanel будет уменьшаться горизонтально на соответствующую сумму, и все содержащиеся элементы управления также будут автоматически уменьшаться.

Ответ 2

Просто убедитесь, что вы инициализируете его следующими свойствами:

this.WrapContents = false;
this.AutoScroll = true;

Вам также необходимо убедиться, что элементы управления, которые вы добавляете к нему, имеют максимальную ширину ширины управления минус ширина полосы прокрутки.

Это должно сделать это, хотя.


Edit:

Я получил это решение из одного из моих пользовательских элементов управления. Похоже, он очень похож на этот пост, но, возможно, я получил его оттуда, я не могу вспомнить. Сообщение, связанное на всякий случай.


Изменить 2:

Поскольку вы уже устанавливаете эти свойства и просматриваете изображение, вам просто нужно сделать элементы управления, которые вы добавляете к узлу FlowPanel, или FlowPanel шире.

В принципе, вам нужно просто разрешить пространство, в котором будет отображаться полоса прокрутки. Вы можете определить, видимо ли это, и заставить внутренние элементы управления соответственно обновить свой макет, если вы действительно хотите использовать всю ширину в любое время.