2010-03-21 20 views
8

Tengo un control ListView en el modo Detalles con una sola columna. Está en un formulario que solo debe usarse con el teclado, principalmente con las flechas arriba/abajo para desplazarse e ingresar para seleccionar. Así que realmente no necesito las barras de desplazamiento y me gustaría que no aparezcan para una apariencia más limpia. Sin embargo, cuando establezco la propiedad ListView.Scrollable en false, aún puedo mover el elemento seleccionado hacia arriba y hacia abajo, pero tan pronto como se mueve a un elemento que no está actualmente a la vista, la lista no se moverá para mostrar ese elemento. He intentado usar EnsureVisible para desplazar la lista por programación, pero no hace nada cuando está en este modo.Cómo ocultar la barra de desplazamiento vertical en .NET Control ListView en modo Detalles

¿Hay alguna manera de mover manualmente la lista hacia arriba y hacia abajo para desplazarse, pero sin tener la barra de desplazamiento presente?

Respuesta

13

No es fácil, pero se puede hacer. Si intenta ocultar la barra de desplazamiento a través de ShowScrollBar, el ListView simplemente lo volverá a poner. Entonces tienes que hacer algo más tortuoso.

Tendrá que interceptar el mensaje WM_NCCALCSIZE, y allí, desactivar el estilo de desplazamiento vertical. Siempre que la vista de lista intente encenderlo nuevamente, lo apagará nuevamente en este controlador.

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); 
} 

Esto le dará un ListView sin barras de desplazamiento que aún se desplaza al utilizar las teclas de flecha para cambiar la selección.

+0

¡Funciona perfecto, gracias! –

+0

Probé el mismo código para desplazamiento horizontal (reemplacé 0x00200000 por 0x00100000), la barra de desplazamiento está oculta pero no puedo desplazarme con las teclas de flecha. ¿Alguna idea? –

0

Llame al método ShowScrollBar API.

+0

Usado [DllImport ("user32.dll")] static extern bool ShowScrollBar (IntPtr hWnd, int wBar, bool bShow); Con: ShowScrollBar (lstMain.Handle, 3, falso); Y no funcionó ... –

+0

¿Qué devolvió? – SLaks

+0

devuelto verdadero (significa éxito) pero realmente no funcionó – Nagg

0

Si ShowScrollBar no funciona, no estoy seguro de cómo hacerlo.

se puede poner la ListView en un panel y hacer que el ListView más ancho que el panel de manera que la barra de desplazamiento se corta (marque SystemInformation.VerticalScrollBarWidth), pero eso es un feo corte terriblemente.

1

Desde ShowScrollBar no funcionó, tal vez esto ayuda:

[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); 
} 
+0

Lo siento. Fuente fija. – Nagg

1

hice algo más fácil. Dejé la función de desplazamiento en true y utilicé un control deslizante personalizado (colorSlider) que encontré en codeproject y dibujé el control deslizante sobre la posición donde aparecería el control de desplazamiento y luego utilicé la función ensureVisible.

0

Puede usar ListView.Scrollable Property. ¡Establézcalo en falso y las barras de desplazamiento no aparecerán!

Cuestiones relacionadas