2011-10-09 63 views
3

將鼠標懸停在列標題上時,在Windows資源管理器中(至少在Win7中),將出現一個帶箭頭的篩選器框,用於篩選結果ListView,因此,例如,您只能顯示以「A」或文件> 128 MB開頭的文件。可以在C#中的基本ListView控件中啓用此功能,而無需創建子類或修改ListView?將篩選器框添加到C#和WinForms中ListView的列標題中

回答

4

這裏有一些代碼可以玩。爲您的項目添加一個新類並粘貼下面顯示的代碼。編譯。將新的ListViewEx控件從工具箱的頂部拖放到表單上。在窗體構造函數中,調用SetHeaderDropdown()方法啓用該按鈕。實現HeaderDropdown事件以返回要顯示的控件。例如:

public partial class Form1 : Form { 
    public Form1() { 
     InitializeComponent(); 
     listViewEx1.SetHeaderDropdown(0, true); 
     listViewEx1.HeaderDropdown += listViewEx1_HeaderDropdown; 
    } 

    void listViewEx1_HeaderDropdown(object sender, ListViewEx.HeaderDropdownArgs e) { 
     e.Control = new UserControl1(); 
    } 
} 

下面的代碼有一個缺陷,彈出窗口顯示在窗體中。這不能太小,並把重點從主要形式。在提示上檢查this answer如何實現一個可以顯示爲頂層窗口而不需要表單的控件。代碼:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Drawing; 
using System.Windows.Forms; 
using System.Runtime.InteropServices; 

class ListViewEx : ListView { 
    public class HeaderDropdownArgs : EventArgs { 
     public int Column { get; set; } 
     public Control Control { get; set; } 
    } 
    public event EventHandler<HeaderDropdownArgs> HeaderDropdown; 

    public void SetHeaderDropdown(int column, bool enable) { 
     if (column < 0 || column >= this.Columns.Count) throw new ArgumentOutOfRangeException("column"); 
     while (HeaderDropdowns.Count < this.Columns.Count) HeaderDropdowns.Add(false); 
     HeaderDropdowns[column] = enable; 
     if (this.IsHandleCreated) SetDropdown(column, enable); 
    } 
    protected void OnHeaderDropdown(int column) { 
     var handler = HeaderDropdown; 
     if (handler == null) return; 
     var args = new HeaderDropdownArgs() { Column = column }; 
     handler(this, args); 
     if (args.Control == null) return; 
     var frm = new Form(); 
     frm.FormBorderStyle = FormBorderStyle.FixedSingle; 
     frm.ShowInTaskbar = false; 
     frm.ControlBox = false; 
     args.Control.Location = Point.Empty; 
     frm.Controls.Add(args.Control); 
     frm.Load += delegate { frm.MinimumSize = new Size(1, 1); frm.Size = frm.Controls[0].Size; }; 
     frm.Deactivate += delegate { frm.Dispose(); }; 
     frm.StartPosition = FormStartPosition.Manual; 
     var rc = GetHeaderRect(column); 
     frm.Location = this.PointToScreen(new Point(rc.Right - SystemInformation.MenuButtonSize.Width, rc.Bottom)); 
     frm.Show(this.FindForm()); 
    } 

    protected override void OnHandleCreated(EventArgs e) { 
     base.OnHandleCreated(e); 
     if (this.Columns.Count == 0 || Environment.OSVersion.Version.Major < 6 || HeaderDropdowns == null) return; 
     for (int col = 0; col < HeaderDropdowns.Count; ++col) { 
      if (HeaderDropdowns[col]) SetDropdown(col, true); 
     } 
    } 

    private Rectangle GetHeaderRect(int column) { 
     IntPtr hHeader = SendMessage(this.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero); 
     RECT rc; 
     SendMessage(hHeader, HDM_GETITEMRECT, (IntPtr)column, out rc); 
     return new Rectangle(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); 
    } 

    private void SetDropdown(int column, bool enable) { 
     LVCOLUMN lvc = new LVCOLUMN(); 
     lvc.mask = LVCF_FMT; 
     lvc.fmt = enable ? LVCFMT_SPLITBUTTON : 0; 
     IntPtr res = SendMessage(this.Handle, LVM_SETCOLUMN, (IntPtr)column, ref lvc); 
    } 

    protected override void WndProc(ref Message m) { 
     Console.WriteLine(m); 
     if (m.Msg == WM_NOTIFY) { 
      var hdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR)); 
      if (hdr.code == LVN_COLUMNDROPDOWN) { 
       var info = (NMLISTVIEW)Marshal.PtrToStructure(m.LParam, typeof(NMLISTVIEW)); 
       OnHeaderDropdown(info.iSubItem); 
       return; 
      } 
     } 
     base.WndProc(ref m); 
    } 

    private List<bool> HeaderDropdowns = new List<bool>(); 

    // Pinvoke 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, ref LVCOLUMN lvc); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, out RECT rc); 
    [DllImport("user32.dll")] 
    private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hParent); 

    private const int LVM_SETCOLUMN = 0x1000 + 96; 
    private const int LVCF_FMT = 1; 
    private const int LVCFMT_SPLITBUTTON = 0x1000000; 
    private const int WM_NOTIFY = 0x204e; 
    private const int LVN_COLUMNDROPDOWN = -100 - 64; 
    private const int LVM_GETHEADER = 0x1000 + 31; 
    private const int HDM_GETITEMRECT = 0x1200 + 7; 


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private struct LVCOLUMN { 
     public uint mask; 
     public int fmt; 
     public int cx; 
     public string pszText; 
     public int cchTextMax; 
     public int iSubItem; 
     public int iImage; 
     public int iOrder; 
     public int cxMin; 
     public int cxDefault; 
     public int cxIdeal; 
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private struct POINT { 
     public int x, y; 
    } 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private struct RECT { 
     public int left, top, right, bottom; 
    } 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private struct NMHDR { 
     public IntPtr hwndFrom; 
     public IntPtr idFrom; 
     public int code; 
    } 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    private struct NMLISTVIEW { 
     public NMHDR hdr; 
     public int iItem; 
     public int iSubItem; 
     public uint uNewState; 
     public uint uOldState; 
     public uint uChanged; 
     public POINT ptAction; 
     public IntPtr lParam; 
    } 
} 
0

這可能是棘手的實現相同類型的接口,但你可以有你的ListViewTextBox的通過處理TextBoxTextChanged事件和過濾基於內容的列表的內容響應。如果您將列表放在DataTable中,那麼過濾將很容易,您可以在每次過濾器更改時重新填充ListView

當然這取決於列表中有多少項目。

+0

謝謝,但我必須添加一個文本框爲每列,即使這樣我也不會弄的Windows資源管理器過濾箱與複選框的選擇(多選可能)名單。我正在尋找完全相同的功能,而不是另一種方式...... – mlessard

+0

在這種情況下,不,ListView不支持這種類型的功能,而無需修改。 –

相關問題