Настройка полосы прокрутки Windows Form - PullRequest
7 голосов
/ 01 декабря 2010

Я искал во всемирной сети без правильного ответа.

В моем приложении Windows Form я хочу изменить ширину полосы прокрутки, принадлежащей FlowLayoutPanel.

Полоса прокруткидобавляется "автоматически", так как содержимое панели макета потока больше формы.

Из того, что я нашел в Интернете, это кажется хитрым.

Есть ли какое-либо решениек этому?

ура!

Ответы [ 2 ]

17 голосов
/ 01 декабря 2010

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

Ужасная правда в том, что простой элемент прокрутки гораздо сложнее, чем кажется.По сути, полосы прокрутки на FlowLayoutPanel отрисовываются самой Windows (а не .NET Framework) из-за стилей окон WS_HSCROLL и / или WS_VSCROLL, которые установлены для скрытого элемента управления.FlowLayoutPanel не предоставляет никаких средств для изменения или изменения способа отображения этих встроенных полос прокрутки.В отличие от других более сложных модификаций в WinForms, нет таких сообщений, которые мы можем отправить в оконную процедуру элемента управления.И что еще хуже, полосы прокрутки отрисовываются в не-клиентской области FlowLayoutPanel, что означает, что мы не можем просто переопределить его событие Paint и сами обрабатывать отрисовку полос прокрутки.

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

1 голос
/ 17 января 2018

Ответ Коди Грея является на 100% правильным, хотя я хотел добавить больше справочного материала по теме.

Фон

Способ, которым Windows Forms создает полосы прокруткичерез использование стилей окна WS_HSCROLL и WS_VSCROLL.Соответственно, эти стили отвечают за включение горизонтальной и вертикальной полос прокрутки для данного HWND.HWND - это собственный дескриптор ресурса для "окна" , которое в .NET lingo соответствует Control.

Думая с точки зрения Windows API, мы должны установить окностили в то время, когда мы создаем HWND.Это делается с помощью вызова CreateWindow, CreateWindowEx или SetWindowLong.Естественно, мы можем начать задумываться об использовании P / Invoke , чтобы выручить нас, но это было бы довольно обременительно, так как это означает, что нам нужно будет заново внедрить Windows Forms с нуля.

К счастью, Windows Forms предоставляет свойство CreateParams, которое можно переопределить, чтобы указать точные стили окна, среди других Control параметров создания.Это свойство, в свою очередь, используется платформой .NET, чтобы при создании экземпляра Control можно было создать HWND с соответствующими стилями.

Настройка полосы прокрутки

Замена WindowsФункциональность API для полосы прокрутки на самом деле проще, чем может показаться;однако, это не очевидно (для меня в любом случае, мне пришлось просеять источник .NET, чтобы найти ответ).Для этого мы должны выбрать соответствующий Control для наследования, чтобы создать свой собственный ScrollableControl .Если мы наблюдаем исходный код для System.Windows.Forms.ScrollableControl, мы видим, что используются следующие стили:

CreateParams cp = base.CreateParams;

if (HScroll || HorizontalScroll.Visible) {
    cp.Style |= NativeMethods.WS_HSCROLL;
}
else {
    cp.Style &= (~NativeMethods.WS_HSCROLL);
}
if (VScroll || VerticalScroll.Visible) {
    cp.Style |= NativeMethods.WS_VSCROLL;
}
else {
    cp.Style &= (~NativeMethods.WS_VSCROLL);
}

Итак, вкратце, когда мы расширяемся от ScrollableControl, собственная горизонтальнаяи вертикальные полосы прокрутки включены на основе его внутренней логики.Мы можем получить доступ к дескриптору окна ScrollableControl и затем вызвать SetWindowLong, чтобы скрыть полосы прокрутки;однако нам нужно было бы отслеживать все места, которые ScrollableControl взаимодействует с Windows API.Фактически существует внутренняя функция Control.UpdateStylesCore(), которая вызывается в зависимости от того, должны ли отображаться полосы прокрутки.Эта функция эффективно применяет стили окон выше, и было бы лучше не бороться с этим.Было бы намного более чистым подходом избегать Windows API и расширяться непосредственно от Control.Затем мы можем предоставить любой API-интерфейс, который нам нужен.

Это означает, что мы будем рассматривать повторную реализацию:

  1. Обновление полос прокрутки для событий колеса мыши.
  2. Обновление полос прокрутки на основе нажатия пользовательских кнопок полосы прокрутки и треков / превью.
  3. Обновление полос прокрутки на основе добавления / удаления / перемещения / изменения размера дочерних элементов управления.
  4. Создание полей автоматической прокрутки.
  5. Ограничения в клиентской области, которые влияют на видимость полос прокрутки.
  6. И так далее ...

В качестве альтернативы, простой подход может заключаться в создании нового UserControl.Это позволило бы нам использовать дизайнер Visual Studio для упрощения настройки кнопок и дорожек полосы прокрутки.

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

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