Как скрыть вертикальную полосу прокрутки в элементе управления.NET ListView в режиме сведений
У меня есть элемент управления ListView в режиме детализации с одним столбцом. Он находится в форме, предназначенной для использования только с клавиатурой, в основном со стрелками вверх / вниз для прокрутки и ввода для выбора. Поэтому мне не нужно иметь полосы прокрутки, и я просто хотел бы, чтобы они не показывались для более чистого вида. Однако, когда я установил для свойства ListView. Scrollable значение false, я все еще могу перемещать выбранный элемент вверх и вниз, но как только он перемещается к элементу, который в данный момент не отображается, список не будет перемещаться, чтобы показать этот элемент. Я пытался использовать EnsureVisible для программной прокрутки списка, но он ничего не делает в этом режиме.
Есть ли способ вручную переместить список вверх и вниз для прокрутки, но без наличия полосы прокрутки?
6 ответов
Это не легко, но это может быть сделано. Если вы попытаетесь скрыть полосу прокрутки в ShowScrollBar, ListView просто вернет ее обратно. Таким образом, вы должны сделать что-то более коварное.
Вам нужно будет перехватить сообщение WM_NCCALCSIZE и там отключить стиль вертикальной прокрутки. Всякий раз, когда просмотр списка пытается включить его снова, вы снова выключите его в этом обработчике.
public class ListViewWithoutScrollBar : ListView
{
protected override void WndProc(ref Message m) {
switch (m.Msg) {
case 0x83: // WM_NCCALCSIZE
int style = (int)GetWindowLong(this.Handle, GWL_STYLE);
if ((style & WS_VSCROLL) == WS_VSCROLL)
SetWindowLong(this.Handle, GWL_STYLE, style & ~WS_VSCROLL);
base.WndProc(ref m);
break;
default:
base.WndProc(ref m);
break;
}
}
const int GWL_STYLE = -16;
const int WS_VSCROLL = 0x00200000;
public static int GetWindowLong(IntPtr hWnd, int nIndex) {
if (IntPtr.Size == 4)
return (int)GetWindowLong32(hWnd, nIndex);
else
return (int)(long)GetWindowLongPtr64(hWnd, nIndex);
}
public static int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong) {
if (IntPtr.Size == 4)
return (int)SetWindowLongPtr32(hWnd, nIndex, dwNewLong);
else
return (int)(long)SetWindowLongPtr64(hWnd, nIndex, dwNewLong);
}
[DllImport("user32.dll", EntryPoint = "GetWindowLong", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowLong32(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "GetWindowLongPtr", CharSet = CharSet.Auto)]
public static extern IntPtr GetWindowLongPtr64(IntPtr hWnd, int nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLong", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowLongPtr32(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, int dwNewLong);
}
Это даст вам ListView без полос прокрутки, который все еще прокручивается при использовании клавиш со стрелками для изменения выбора.
Я сделал что-то более легкое я оставил прокручиваемое значение true и использовал пользовательский ползунок (colorSlider), который я нашел в codeproject, и нарисовал ползунок над положением, где должен появиться vscroller, а затем использовал функцию sureVisible.
Поскольку ShowScrollBar не работает, возможно, это поможет:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
private const int WM_VSCROLL = 0x115;
private const int SB_LINEDOWN = 1;
public Form1()
{
InitializeComponent();
for (int i = 0; i < 100; i++)
listView1.Items.Add("foo" + i);
listView1.Scrollable = false;
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
SendMessage(listView1.Handle, WM_VSCROLL, SB_LINEDOWN, 0);
}
Вы можете использовать ListView.Scrollable Property. Установите значение false, и полосы прокрутки не появятся!
Если ShowScrollBar
не работает, я не уверен, как это сделать.
Вы можете поместить ListView на панель и сделать ListView шире, чем панель, чтобы полоса прокрутки была обрезана (проверьте SystemInformation.VerticalScrollBarWidth
), но это ужасно безобразный хак.