2010-03-21 40 views
8

Tôi có một điều khiển ListView trong Chế độ chi tiết với một cột đơn. Đó là trên một hình thức đó là có nghĩa là để chỉ được sử dụng với bàn phím, chủ yếu là với các mũi tên lên/xuống để di chuyển và nhập để chọn. Vì vậy, tôi không thực sự cần phải có các thanh cuộn và sẽ giống như họ không hiển thị cho một cái nhìn sạch hơn. Tuy nhiên, khi tôi đặt thuộc tính ListView.Scrollable thành false, tôi vẫn có thể di chuyển mục đã chọn lên và xuống, nhưng ngay khi nó di chuyển đến một mục không có trong chế độ xem, danh sách sẽ không di chuyển để hiển thị mục đó. Tôi đã thử bằng cách sử dụng EnsureVisible để lập trình cuộn danh sách, nhưng nó không có gì khi ở chế độ này.Cách ẩn thanh cuộn dọc trong Điều khiển .NET ListView trong Chế độ chi tiết

Có cách nào để di chuyển danh sách lên và xuống theo cách thủ công để cuộn, nhưng không có thanh cuộn hiện tại?

Trả lời

13

Nó không phải dễ dàng, nhưng nó có thể được thực hiện. Nếu bạn cố gắng ẩn thanh cuộn qua ShowScrollBar, ListView sẽ chỉ đơn giản là đưa nó trở lại. Vì vậy, bạn phải làm điều gì đó đáng sợ hơn.

Bạn sẽ phải chặn thông báo WM_NCCALCSIZE và trong đó, tắt kiểu cuộn dọc. Bất cứ khi nào listview cố gắng bật lại, bạn sẽ tắt nó một lần nữa trong trình xử lý này.

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

Điều này sẽ cung cấp cho bạn một ListView mà không có thanh cuộn vẫn cuộn khi bạn sử dụng các phím mũi tên để thay đổi lựa chọn.

+0

Hoạt động hoàn hảo, cảm ơn bạn! –

+0

Tôi đã thử cùng một mã cho cuộn ngang (tôi đã thay thế 0x00200000 bằng 0x00100000), thanh cuộn được ẩn nhưng tôi không thể cuộn bằng các phím mũi tên. Bất kỳ ý tưởng? –

0

Gọi phương thức API ShowScrollBar.

+0

Được sử dụng [DllImport ("user32.dll")] static extern bool ShowScrollBar (IntPtr hWnd, int wBar, bool bShow); Với: ShowScrollBar (lstMain.Handle, 3, false); Và nó không hoạt động ... –

+0

Nó đã trở lại cái gì? – SLaks

+0

trả về true (có nghĩa là thành công) nhưng nó thực sự không hoạt động – Nagg

0

Nếu ShowScrollBar không hoạt động, tôi không chắc chắn cách thực hiện.

Bạn có thể đặt ListView trong một bảng điều khiển và làm cho ListView rộng hơn so với bảng điều khiển để các thanh cuộn được cắt đứt (kiểm tra SystemInformation.VerticalScrollBarWidth), nhưng đó là một horrifyingly xấu xí hack.

1

Kể từ ShowScrollBar đã không làm việc, có lẽ đây sẽ giúp:

[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

Xin lỗi. Nguồn cố định. – Nagg

1

tôi đã làm điều gì đó dễ dàng hơn. tôi có thể cuộn lại thành true và sử dụng một thanh trượt tùy chỉnh (colorSlider) mà tôi tìm thấy trên codeproject và tôi vẽ thanh trượt trên vị trí mà vscroller sẽ xuất hiện và sau đó sử dụng hàm EnsureVisible.

0

Bạn có thể sử dụng thuộc tính ListView.Scrollable. Đặt nó thành false và thanh cuộn sẽ không xuất hiện!

Các vấn đề liên quan