首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > .NET > VB.NET > 三種實現 ListView 欄位排序指標(Up/Down Arrow)的方法
【标  题】:三種實現 ListView 欄位排序指標(Up/Down Arrow)的方法
【关键字】:ListView,Up/Down,Arrow
【来  源】:http://blog.joycode.com/fish/archive/2004/08/22/31275.aspx

三種實現 ListView 欄位排序指標(Up/Down Arrow)的方法


現有的ListView控件中實行Sort並無類似Datagrid欄位的排序指標顯示,
在.NET Framework 1.0/1.1也沒有客製化ListView ColumnHeader的功能(2.0已有)
因此想要顯示排序指標必須透過其他方法來實現, 以下例舉了三個不同的方法來實現這項功能
完整程式可參考原網址.
1. http://groups.google.com.tw/groups hl=zh-TW&lr=&ie=UTF-8&selm=eci6b0lfbi607ru0hbrs6nca6379coes2i%404ax.com
透過繪製指標的方式實現, 透過API開啟欄位支援img圖像功能並傳送相對指標.
Public Class ListViewSort
  _
  Public Structure HDITEM
      Public mask As Int32
      Public cxy As Int32
      _
      Public pszText As String
      Public hbm As IntPtr
      Public cchTextMax As Int32
      Public fmt As Int32
      Public lParam As Int32
      Public iImage As Int32
      Public iOrder As Int32
  End Structure

  Const HDI_FORMAT As Int32 = 4
  Const HDI_IMAGE As Int32 = 32
  Const HDF_LEFT As Int32 = 0
  Const HDF_RIGHT As Int32 = 1
  Const HDF_CENTER As Int32 = 2
  Const HDF_STRING As Int32 = 16384
  Const HDF_BITMAP_ON_RIGHT As Int32 = 4096
  Const HDF_IMAGE As Int32 = 2048
  Const HDF_SORTUP As Int32 = 1024
  Const HDF_SORTDOWN As Int32 = 512
  Const LVM_FIRST As Int32 = 4096
  Const LVM_GETHEADER As Int32 = LVM_FIRST + 31
  Const HDM_FIRST As Int32 = 4608
  Const HDM_SETIMAGELIST As Int32 = HDM_FIRST + 8
  Const HDM_SETITEM As Int32 = HDM_FIRST + 12

  Public Sub ShowHeaderIcon(ByVal list As ListView, ByVal columnIndex As Integer, ByVal sortOrder As SortOrder)
      If columnIndex < 0 OrElse columnIndex >= list.Columns.Count Then
          Return
      End If
      Dim hHeader As IntPtr = SendMessage(list.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero)
      Dim colHdr As ColumnHeader = list.Columns(columnIndex)
      Dim hd As HDITEM = New HDITEM
      hd.mask = HDI_IMAGE Or HDI_FORMAT
      Dim align As HorizontalAlignment = colHdr.TextAlign
      If align = HorizontalAlignment.Left Then
          hd.fmt = HDF_LEFT Or HDF_STRING Or HDF_BITMAP_ON_RIGHT
      Else
          If align = HorizontalAlignment.Center Then
              hd.fmt = HDF_CENTER Or HDF_STRING Or HDF_BITMAP_ON_RIGHT
          Else
              hd.fmt = HDF_RIGHT Or HDF_STRING
          End If
      End If
      If Not (sortOrder = sortOrder.None) Then
          hd.fmt = hd.fmt Or (HDF_IMAGE)
      End If
      hd.iImage = CType(sortOrder, Integer) - 1
      SendMessage(hHeader, HDM_SETITEM, New IntPtr(columnIndex), hd)
  End Sub

  Public Sub SetHeaderImageList(ByVal list As ListView)
      Dim hHeader As IntPtr = SendMessage(list.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero)
      SendMessage(hHeader, HDM_SETIMAGELIST, IntPtr.Zero, m_imgList.Handle)
  End Sub

  _
  Shared Function SendMessage(ByVal Handle As IntPtr, ByVal msg As Int32, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
  End Function

  _
  Shared Function SendMessage(ByVal Handle As IntPtr, ByVal msg As Int32, ByVal wParam As IntPtr, ByRef lParam As HDITEM) As IntPtr
  End Function

  Private m_imgList As ImageList
  Public Sub New()
      m_imgList = New ImageList
      m_imgList.ImageSize = New Size(8, 8)
      m_imgList.TransparentColor = System.Drawing.Color.Magenta
      m_imgList.Images.Add(GetArrowBitmap(ArrowType.Ascending))
      m_imgList.Images.Add(GetArrowBitmap(ArrowType.Descending))
  End Sub

  Enum ArrowType
      Ascending
      Descending
  End Enum
  Function GetArrowBitmap(ByVal type As ArrowType) As Bitmap
      Dim bmp As New Bitmap(8, 8)
      Dim gfx As Graphics = Graphics.FromImage(bmp)
      Dim lightPen As Pen = SystemPens.ControlLightLight
      Dim shadowPen As Pen = SystemPens.ControlDark
      gfx.FillRectangle(System.Drawing.Brushes.Magenta, 0, 0, 8, 8)
      If type = ArrowType.Ascending Then
          gfx.DrawLine(lightPen, 0, 7, 7, 7)
          gfx.DrawLine(lightPen, 7, 7, 4, 0)
          gfx.DrawLine(shadowPen, 3, 0, 0, 7)
      Else
          gfx.DrawLine(lightPen, 4, 7, 7, 0)
          gfx.DrawLine(shadowPen, 3, 7, 0, 0)
          gfx.DrawLine(shadowPen, 0, 0, 7, 0)
      End If
      gfx.Dispose()
      Return bmp
  End Function
End Class
'注意事項若原Listview已設置imagelist則SetHeaderImageList必須放在imagelist後面執行
否則會指向listview原imagelist上的圖示

2. 針對第一個方法我所作的修改更為精簡
方法同上直接原生API方式實現, 此方法必須在有manifest或EnableVisualStyles開啟的情況下支援
(備註: 1.XP以下的OS不支援, 2.不受Theme關閉的影響)
Public Sub ShowHeaderIcon(ByVal list As ListView, ByVal columnIndex As Integer, ByVal sortOrder As SortOrder)
    If columnIndex < 0 OrElse columnIndex >= list.Columns.Count Then
        Return
    End If
    Dim hHeader As IntPtr = SendMessage(list.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero)
    Dim colHdr As ColumnHeader = list.Columns(columnIndex)
    Dim hd As HDITEM = New HDITEM
    hd.mask = HDI_FORMAT
    Dim align As HorizontalAlignment = colHdr.TextAlign
    If align = HorizontalAlignment.Left Then
        hd.fmt = HDF_LEFT Or HDF_STRING
    Else
        If align = HorizontalAlignment.Center Then
            hd.fmt = HDF_CENTER Or HDF_STRING
        Else
            hd.fmt = HDF_RIGHT Or HDF_STRING
        End If
    End If
    If sortOrder = sortOrder.Ascending Then
        hd.fmt = hd.fmt Or HDF_SORTUP
    ElseIf sortOrder = sortOrder.Descending Then
        hd.fmt = hd.fmt Or HDF_SORTDOWN
    End If
    SendMessage(hHeader, HDM_SETITEM, New IntPtr(columnIndex), hd)
End Sub

3. http://groups.google.com.tw/groups hl=zh-TW&lr=&ie=UTF-8&selm=1092127868.280097%40news.thyssen.com
透過Unicode文字指標方式實現, 實作的方式最為簡單容易.
Dim mSortDirection As String = "ASC"
Private SortColumn As Integer = 1
Protected Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
    'remove sort icon from old column.
    If SortColumn <> -1 Then
        ListView1.Columns.Item(SortColumn).Text = ListView1.Columns.Item(SortColumn).Text.TrimEnd(Chr(32), Chr(32), Chr(32), ChrW(&H25B2), ChrW(&H25BC))
    End If
    If e.Column <> SortColumn Then
        SortColumn = e.Column
        mSortDirection = "ASC"
        'add down icon
        ListView1.Columns.Item(SortColumn).Text &= " " & ChrW(&H25B2)
    Else
        If mSortDirection = "ASC" Then
            mSortDirection = "DESC"
            'do the sort
            'add down icon
            ListView1.Columns.Item(SortColumn).Text &= " " & ChrW(&H25BC)
        Else
            mSortDirection = "ASC"
            'do the sort
            'add up icon
            ListView1.Columns.Item(SortColumn).Text &= " " & ChrW(&H25B2)
        End If
    End If
End Sub

Code Library .NET 9.0 Beta 與 Blog 之應用:【上一篇】
IE6 中 FieldSet Tag 的bug:【下一篇】
【相关文章】
  • 實現 ListView 控制項的 FindItem 方法 (WinForm)
  • ListView Control 意外引發單擊事件的錯誤
  • ListView扩展
  • ListView视图中无法使用派生的CListCtrl类。
  • VB.NET中LISTVIEW排序(原创)
  • 在Visual C#中用ListView显示数据记录
  • ListView的排序
  • 读取其他应用程序中ListView中的内容
  • 设置ListView的页眉图标
  • 获取其他进程中ListView的文本
  • 【随机文章】
  • 构想本身不具有意义--亚马逊书店的成功秘诀
  • 这个书里的程序好象错了?
  • C++ Builder初学问与答3
  • 发布一个taglib:+
  • 数据库做什么最耗CPU资源及alter和update的区别
  • 8000元工资软件设计师考题
  • 用scanf实现gets的功能
  • 语言之争-开发人员不可以回避的现实
  • Eiger:让老化的电脑活起来!
  • Buider模式应用实践
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.