Ответ Коди Грея является на 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-интерфейс, который нам нужен.
Это означает, что мы будем рассматривать повторную реализацию:
- Обновление полос прокрутки для событий колеса мыши.
- Обновление полос прокрутки на основе нажатия пользовательских кнопок полосы прокрутки и треков / превью.
- Обновление полос прокрутки на основе добавления / удаления / перемещения / изменения размера дочерних элементов управления.
- Создание полей автоматической прокрутки.
- Ограничения в клиентской области, которые влияют на видимость полос прокрутки.
- И так далее ...
В качестве альтернативы, простой подход может заключаться в создании нового UserControl
.Это позволило бы нам использовать дизайнер Visual Studio для упрощения настройки кнопок и дорожек полосы прокрутки.
Какой бы путь ни был выбран, необходимо будет увидеть, как ScrollableControl
работает внутри, чтобы обеспечить удобную работу пользователя.опыт.