AutoCompleteBoxとLongListSelectorコントロールを使う

2011年8月22日(月)
PROJECT KySS

次に、ソリューションエクスプローラー内のMainPage.xamlを展開し、表示されるMainPage.xaml.vbをダブルクリックしてリスト6のロジックコードを記述します。

ロジックコードを記述する

リスト6 (MainPage.xaml.vb)

Option Strict On
Imports System.Xml.Linq

PersonalInfoクラス内に、文字列型の「氏名」、「読み」、「年齢」、「住所」、「勤務先」、「区切り」プロパティを定義しておきます。
Public Class PersonalInfo
  Property 氏名 As String
  Property 読み As String
  Property 年齢 As String
  Property 住所 As String
  Property 勤務先 As String
  Property 区切り As String
End Class
Partial Public Class MainPage
  Inherits PhoneApplicationPage
~コード略~

ページが読み込まれた時の処理

XElement.LoadメソッドでXML文書ファイル(sampleData_Group.xml)を読み込みます。
PersonalInfoクラス型の新しいリストであるmyPersonalInfoオブジェクトを生成します。
LINQでは、Group By句を使って、クエリーの結果をグループ化できます。構文は次の通りです。

Group [From句で使用する場合の範囲変数] By [グループを決定するためのキーと式] Into [グループ集計方法の式] 

[グループの集計方法の式]にはInto yomiGroup=Groupと指定しています。yomiGroupは任意の変数名で他の名称でも構いません。コード・エディター上で「yomiGroup=」と入力すると、インテリセンスが働くので「Group」を選択します(図6)。
Order by句では並べ替えを指定できます。ここでは「読み」を昇順(Ascending(規定値))で並べ替えています。降順の場合はDescendingを指定します。
  定義したクエリーのコレクション内を、変数resultを使って反復処理します。反復処理の過程で、yomiGroupという名前で作成されたグループ(result.yomiGroup)のコレクションが取得されます。この中を、再度、反復処理しながら以下の処理を実行します。result.yomiGroupのyomiGroupは、Group By Into句のInto yomiGroup=Groupで使用した変数です。For Eachステートメントを入れ子にすることがポイントです。
PersonalInfoクラスの「氏名、読み、年齢、住所、勤務先」のプロパティに<氏名>、<読み>、<年齢>、<住所>、<勤務先>要素の値を指定します。「区切り」のプロパティには「------------」の文字列を直接指定し、AddメソッドでmyPersonalInfoオブジェクトに追加していきます。
  再度クエリーを定義します。PersonalInfoクラスの各プロパティに値の追加された、myPersonalInfoオブジェクトのコレクションに対して、「読み」でグループ化します。PersonalInfo型のmyGroupクラス(後述)の中で定義している処理に従って、myYomiとmyItemsに値を指定して、再グループ化します。コード・エディター内で、myYomi:=またはmyItems:=と入力するとインテリセンスが働いて、値が表示されますので、その中から選択できます(図7)。myYomi:=に指定した値がヘッダの「読み」となり、myItems:=に指定した値が「グループの中身」となります。
LongListSelectorのItemsSourceに再グループ化したgroupByを指定します。myGroupクラス内のYomiがグループヘッダとなり、グループの中身はItems.GetEnumrator() で取得しています。
  Private Sub MainPage_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
    Dim xmldoc As XElement = XElement.Load("sampleData_Group.xml")
    Dim myPersonalInfo As New List(Of PersonalInfo)
    Dim query = From c In xmldoc.Elements("情報") Order By c.Element("読み").Value Group c By c.Element("読み").Value Into yomiGroup = Group
 
    For Each result In query
      For Each result2 In result.yomiGroup
        With myPersonalInfo
          .Add(New PersonalInfo With {.氏名 = result2.Element("氏名").Value,
                                                     .読み = result2.Element("読み").Value,
                                                     .年齢 = result2.Element("年齢").Value,
                                                     .住所 = result2.Element("住所").Value,
                                                     .勤務先 = result2.Element("勤務先").Value,
                                                     .区切り = "--------------------------"})
        End With
      Next
    Next
    Dim groupBy = From c In myPersonalInfo Group c By c.読み Into myYomiGroup= Group Select New myGroup(Of PersonalInfo)(myYomi:=読み, myItems:=myYomiGroup)
    LongListSelector1.ItemsSource = groupBy
  End Sub

データ型を特定しないジェネリック型のmyGroupクラスを作成します。ジェネリック型IEnumerable(Of T)を実装します。IEnumerable(Of T)は、コレクションに対する単純な反復処理をサポートする列挙子を公開します。
Implements IEnumerable(Of T)と記述すると、自動的に下記の2つコードが追加されます。

  Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator

  End Function
  
  Public Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
 
  End Function

myGroupクラス内で、文字列型のYomiプロパティ(グループヘッダとなる「読み」)と、インデックスによって個別にアクセスできるオブジェクトのコレクションを表すIList(Of T)型のItemsプロパティ(グループの中身)を定義しておきます。YomiとItemsプロパティに値を代入します。これで、「読み」とインデックス付きの「読みのグループ一覧」を保持しています。
Equalsメソッドをオーバーライドします。グループヘッダの「読み」がクリックされた時、その「読み」に該当する内容が先頭に表示されます。
自動的に追加された上記2つのコード内では、Items.GetEnumeratorを戻り値としています。これでグループの中身を、反復処理して取得して返しています。
  Public Class myGroup(Of T)
    Implements IEnumerable(Of T)
    Property Yomi As String
    Property Items As IList(Of T)
    Public Sub New(myYomi As String, myItems As IEnumerable(Of T))
      Yomi = myYomi
      Items = New List(Of T)(myItems)
    End Sub
 
    Public Overrides Function Equals(obj As Object) As Boolean
      Dim selectData As myGroup(Of T) = TryCast(obj, myGroup(Of T))
      Return Yomi.Equals(selectData.Yomi)
    End Function
 
    Public Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
      Return Items.GetEnumerator
    End Function
 
    Public Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
      Return Items.GetEnumerator
    End Function
  End Class
End Class

3

図6:コード・エディター上で「yomiGroup=」と入力すると、インテリセンスが働くので「Group」を選択する(クリックで拡大)

3

図7:コード・エディター内で、myYomi:=またはmyItems:=と入力するとインテリセンスが働いて、値が表示される。その中から選択できる(クリックで拡大)
  • 「AutoCompleteBoxとLongListSelectorコントロールを使う」サンプルプログラム_1

  • 「AutoCompleteBoxとLongListSelectorコントロールを使う」サンプルプログラム_2

四国のSOHO。薬師寺国安(VBプログラマ)と、薬師寺聖(デザイナ、エンジニア)によるコラボレーション・ユニット。1997年6月、Dynamic HTMLとDirectAnimationの普及を目的として結成。共同開発やユニット名義での執筆活動を行う。XMLおよび.NETに関する著書や連載多数。最新刊は「Silverlight実践プログラミング」両名とも、Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。http://www.PROJECTKySS.NET/

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています