SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

ListViewコントロールに柔軟なソート機能を追加する

ListViewクラスを拡張したSortableListViewクラスの作成

ダウンロード サンプルソース (57.9 KB)

SelectedColumnSorterクラスを使う

 これで、SortableListViewコントロールはSelectedColumnSorterクラスを使って特定の列によるソートを実行できる状態になりました。リスト1に、SortableListViewコントロールの重要なコード部分を示します。話を単純にするために、選択した列によるソート処理に関係のないコードは省略しています。

リスト1
Imports System.ComponentModel

<ToolboxBitmap(GetType(SortableListView), _
    "tbxSortableListView")> _
Public Class SortableListView
    Inherits ListView

    Public Enum SortStyles
        SortDefault
        SortAllColumns
        SortSelectedColumn
    End Enum

    ' The current sort column for selected column sorting.
    Private m_SelectedColumn As Integer = -1

    ' Whether we sort by all columns, one column, or not at all.
    Private m_SortStyle As SortStyles = SortStyles.SortDefault
    Public Property SortStyle() As SortStyles
        Get
            Return m_SortStyle
        End Get
        Set(ByVal value As SortStyles)
            ' If the current style is SortSelectedColumn,
            ' remove the column sort indicator.
            If m_SortStyle = SortStyles.SortSelectedColumn Then
                If m_SelectedColumn >= 0 Then
                    Me.Columns(m_SelectedColumn).ImageKey = _
                        Nothing
                    m_SelectedColumn = -1
                End If
            End If

            ' Save the new value.
            m_SortStyle = value

            Select Case m_SortStyle
                Case SortStyles.SortDefault
                    Me.ListViewItemSorter = Nothing
                Case SortStyles.SortAllColumns
                    Me.ListViewItemSorter = New AllColumnSorter()
                Case SortStyles.SortSelectedColumn
                    Me.ListViewItemSorter = _
                        New SelectedColumnSorter()
            End Select

            ' Resort.
            ' Me.Sort()
        End Set
    End Property

    ' Change the selected sort column.
    Protected Overrides Sub OnColumnClick( _
     ByVal e As System.Windows.Forms.ColumnClickEventArgs)
        MyBase.OnColumnClick(e)

        If Me.SortStyle = SortStyles.SortSelectedColumn Then
            ' If this is the same sort column, switch the
            ' sort order.
            If e.Column = m_SelectedColumn Then
                If Me.Sorting = SortOrder.Ascending Then
                    Me.Sorting = SortOrder.Descending
                Else
                    Me.Sorting = SortOrder.Ascending
                End If
            End If

            ' Remove the image from the previous sort column.
            If m_SelectedColumn >= 0 Then
                Me.Columns(m_SelectedColumn).ImageKey = Nothing
            End If

            ' If we're not currently sorting, sort ascending.
            If Me.Sorting = SortOrder.None Then
                Me.Sorting = SortOrder.Ascending
            End If

            ' Save the new sort column and give it an image.
            m_SelectedColumn = e.Column
            If Me.Sorting = SortOrder.Descending Then
                Me.Columns(m_SelectedColumn).ImageKey = _
                    "sortDescending.bmp"
            Else
                Me.Columns(m_SelectedColumn).ImageKey = _
                    "sortAscending.bmp"
            End If

            ' Resort.
            Me.Sort()
        End If
    End Sub
End Class

 リスト1のコードには、名前空間System.ComponentModelのインポート後に、ToolboxBitmap属性と、SortableListViewコントロールがListViewを継承していることを示すClassステートメントが記されています。

<ToolboxBitmap(GetType(SortableListView), _
    "tbxSortableListView")> _
Public Class SortableListView

 SortableListViewコントロールでは、SortStyles列挙体を定義しています。これは、デフォルトのメソッドを使ったソート、すべての列によるソート、選択した列によるソートのどれを行うかを指定するためのものです。

Public Enum SortStyles
   SortDefault
   SortAllColumns
   SortSelectedColumn
End Enum

 また、ソートに用いる列のインデックスを保持するm_SelectedColumn変数も宣言されています。

 SortStyleプロパティは、SortStyles列挙体の値の取得および設定に用います。Getプロシージャは、m_SortStyle変数の保持する値を返すだけのものです。

Public Property SortStyle() As SortStyles
   Get
      Return m_SortStyle
   End Get
   ...

 一方、リスト1のSetプロシージャは、もう少し複雑な働きをします。まず、現時点でこのコントロールが「選択した列によるソート」を行おうとしているかどうかをチェックします。その場合は、その列に画像が一切表示されないように、列のImageKeyプロパティをNothingにして、ソート方向インジケータ(ソート方向を示す矢印)を取り除きます。

Set(ByVal value As SortStyles)
   ' If the current style is SortSelectedColumn,
   ' remove the column sort indicator.
   If m_SortStyle = SortStyles.SortSelectedColumn Then
      If m_SelectedColumn >= 0 Then
         Me.Columns(m_SelectedColumn).ImageKey = Nothing
         m_SelectedColumn = -1
      End If
   End If
   ...

 次にSetプロシージャは、新しいソート形式を保存したうえで、Select Caseステートメントによって適切な処理に分岐します。新しいソート形式がSortDefaultのときは、ListViewItemSorterプロパティにNothingが設定され、ListViewのデフォルトのソート処理がそのまま実行されることになります。ソート形式がSortAllColumnsのときは、ListViewItemSorterプロパティに新しいAllColumnSorterオブジェクト(後述)が設定されます。ソート形式がSortSelectedColumnのときは、ListViewItemSorterプロパティに新たなSelectedColumnSorterが設定されます。

   ...
   ' Save the new value.
   m_SortStyle = value

      Select Case m_SortStyle
      Case SortStyles.SortDefault
         Me.ListViewItemSorter = Nothing
      Case SortStyles.SortAllColumns
         Me.ListViewItemSorter = New AllColumnSorter()
      Case SortStyles.SortSelectedColumn
         Me.ListViewItemSorter = _
             New SelectedColumnSorter()
      End Select

      ' Resort.
      ' Me.Sort()
   End Set
End Property

 Setプロシージャでは、この時点でSortableListViewコントロールのSortメソッドを呼び出し、この新たなソータを使って各アイテムを再ソートすることも可能です。ただし、このやり方は分かりにくいので、サンプルプログラムではその部分をコメントアウトしてメインプログラムからSortableListViewコントロールのSortメソッドを呼び出すようにしています。

 SortableListViewコントロールで列のソートを行うために必要な最後の部分が、列ヘッダをユーザーがクリックするたびに呼び出されるOnColumnClickメソッドです。このメソッドのコードは、ベースクラスのOnColumnClickメソッドの呼び出しから始まります。続いて、現在のソート形式がSortSelectedColumnかどうかの判断を行います。

Protected Overrides Sub OnColumnClick( _
   ByVal e As System.Windows.Forms.ColumnClickEventArgs)

   MyBase.OnColumnClick(e)

   If Me.SortStyle = SortStyles.SortSelectedColumn Then
      ' If this is the same sort column, switch the sort order.
      If e.Column = m_SelectedColumn Then
         If Me.Sorting = SortOrder.Ascending Then
            Me.Sorting = SortOrder.Descending
         Else
            Me.Sorting = SortOrder.Ascending
         End If
      End If

      ' Remove the image from the previous sort column.
      If m_SelectedColumn >= 0 Then
         Me.Columns(m_SelectedColumn).ImageKey = Nothing
      End If

      ' If we're not currently sorting, sort ascending.
      If Me.Sorting = SortOrder.None Then
         Me.Sorting = SortOrder.Ascending
      End If

      ' Save the new sort column and give it an image.
      m_SelectedColumn = e.Column
      If Me.Sorting = SortOrder.Descending Then
         Me.Columns(m_SelectedColumn).ImageKey = _
             "sortDescending.bmp"
      Else
         Me.Columns(m_SelectedColumn).ImageKey = _
             "sortAscending.bmp"
      End If

      ' Resort.
      Me.Sort()
   End If
End Sub

 直前に選択されていたのと同じ列をユーザーがクリックすると、上記のOnColumnClickメソッドのコードによってSortableListViewコントロールのソート方向が切り換わり、ソート方向インジケータが消去されます。現在のソート方向が選択されていない場合は、デフォルトである昇順が用いられます。

 次に、新たにクリックされた列を選択した列として保存し、適切なソート方向のインジケータをその列に設定します。

著者による注釈
 メインプログラムでは、SortableListViewコントロールのSmallImageListプロパティにこうした画像を含むImageListコントロールを設定する必要があります。ImageListにおけるこれらの画像名は、「sortDescending.bmp」と「sortAscending.bmp」にします。画像のサイズを16x14ピクセルにすると最適な表示が得られるようです。

 OnColumnClickのコードでは、最後にSortableListViewコントロールのSortメソッドを呼び出し、新たに選択した列とソート方向に従ってアイテムの再ソートを行います。

次のページ
全列によるソート処理

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Rod Stephens(Rod Stephens)

10冊以上の書籍と200点以上の雑誌記事の著者にしてコンサルタント。著作の大部分はVisual Basicに関するものである。これまで、修復ディスパッチ、燃料税トラッキング、プロフェッショナルなフットボールトレーニング、廃水処理、地図作成、チケット販売などの種々雑多なアプリケーションに従事してきた。彼のWebサイト「VB Helper」は、1か月に7百万以上のヒットを記録しており、Visual Basicプログラマ向けに3つのニューズレターと何千ものヒントや例を提供している。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1333 2007/05/25 10:12

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー