SHOEISHA iD

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

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

現役エンジニア直伝! 「現場」で使えるコンポーネント活用術(FlexGrid)

FlexGridでSilverlight一覧表示を手軽に実装
~DataGridからFlexGridへの移行と性能比較~

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード サンプルソース (1.0 MB)

 Silverlight標準の一覧表示用コントロール「DataGrid」は、凝ったことをやろうとすると、なかなか実現が難しい場合があります。そうした際に使えるのが、FlexGird for Silverlightです。今回は、まずDataGridでTwitter上からハッシュタグのついたTweetを一覧表示する画面を作り、それをFlexGridに移行します。そして、最後に両者の使い勝手を比較してみたいと思います。

  • X ポスト
  • このエントリーをはてなブックマークに追加

DataGrid以上の使いやすさを実現するFlexGrid for Silverlight

 業務用アプリケーションでは、一覧表示が必要になる事がよくあります。業務用アプリケーションでは、画面の使いやすさと同時に、作業効率という面も重要な評価ポイントであり、“一覧性”はその重要なファクターになるからです。

 Silverlightにも一覧表示用にDataGridコントロールがあります。各種データをデータソースとして連結して手軽に一覧表示はできるのですが、データ連結しなければ一覧表示する事ができないなど、凝ったことをやろうとすると、XAMLに対するスキルなどを身に付けていないと実現が難しいときもあります。有識者にとっては「XAMLでできるよ」「一度IEnum・・・で○○してから使えばできるよ」と簡単に説明できる事でも、実は多くの基礎ノウハウがあってこその簡単さだったりします。

 今回紹介するFlexGrid for Silverlightは、様々な設定をプロパティで行えるため、シンプルな操作で目的のデザインを構築できる、使いやすいコンポーネントです。今回は、まずDataGridでTwitter上からハッシュタグのついたTweetを一覧表示する画面を作り、それをFlexGridに移行します。そして、最後に両者の使い勝手を比較してみたいと思います。なお、説明箇所ごとの実装をサンプルソース内に入れてあるので、適宜参照してください。

DataGridで一覧表示画面を実装

 まずは、DataGridで一覧表示画面を実装していきます。

DataGridでの一覧表示画面のデザイン

 ButtonとDataGridを画面上に配置して、Buttonをクリックした時にデータを取得して一覧表示するUIは、次のようなXAML定義になります。

リスト1 DataGridで一覧表示する画面デザイン例
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <Button x:Name="Get_Button" Content="取得" Width="100" 
                    Click="Get_Button_Click" />
        </StackPanel>
        <sdk:DataGrid Grid.Row="1"
                      AutoGenerateColumns="True" 
                      HorizontalAlignment="Left" 
                      x:Name="Result_DataGrid" 
                      VerticalAlignment="Top" 
                      Height="227" 
                      Width="500">
        </sdk:DataGrid>
    </Grid>

 DataGridの定義の重要な点は、次の2点になります。

  • AutoGenerateColumnsを「True」にして、連結したデータソースに合わせて自動的にカラム生成
  • x:Name」として「Result_DataGird」を設定し、コードからDataGridを操作できるように設定

 XAMLで定義した画面を操作したときのイベントとプロシージャを関連づける記述は、2種類の書き方ができます。今回は、XAML側でButtonに対して「Click="Get_Button_Click"」と記述していますが、コード側で「Handles Get_Button.Click」をプロシージャ宣言に追記しても同じ事が可能です。

DataGridにおける一覧表示させるためのコード

 Silverlightでは、HTTP通信はすべて非同期で行うため、DownloadStringAsyncを使ってリクエストを送信し、DownloadStringCompletedイベントによりレスポンスを取得します。

リスト2 DataGridで一覧表示するコード例
Imports System.Runtime.Serialization.Json
Imports System.Text

Partial Public Class MainPage
    Inherits UserControl

    Private WithEvents Webs As New System.Net.WebClient
    Private Const URL As String = "http://hatsune.wankuma.com/service/CZ1103_search.aspx"

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub Get_Button_Click(sender As System.Object,
                                 e As System.Windows.RoutedEventArgs)
        Call GetRecords()
    End Sub

    Private Sub GetRecords()
        Call Webs.DownloadStringAsync(New Uri(URL))
        Me.Get_Button.IsEnabled = False
        Me.Cursor = Cursors.Wait
    End Sub

    Private Sub Webs_DownloadStringCompleted(sender As Object,
                                             e As DownloadStringCompletedEventArgs) _
                                         Handles Webs.DownloadStringCompleted
        Me.Get_Button.IsEnabled = True
        Me.Cursor = Cursors.Arrow
        If e.Error IsNot Nothing Then
            MessageBox.Show(e.Error.Message)
        Else
            Dim serializer As New DataContractJsonSerializer(GetType(TSearchResult))

            Using stream As New System.IO.MemoryStream(Encoding.UTF8.GetBytes(e.Result))
                Dim result As TSearchResult = CType(serializer.ReadObject(stream), TSearchResult)
                Dim view As New Data.PagedCollectionView(result.results)

                view.SortDescriptions.Add(New ComponentModel.SortDescription("create_at", ComponentModel.ListSortDirection.Descending))
                Me.Result_DataGrid.ItemsSource = view
            End Using
        End If
    End Sub

    Public Class TSearch
        Public Property created_at As String
        Public Property from_user As String
        Public Property text As String
    End Class

    Public Class TSearchResult
        Public Property results As List(Of TSearch)
    End Class
End Class

一覧表示の実行

 XAML側とコード側が完成したら実行してみましょう。

 IDEから実行すれば自動的にWebブラウザが立ち上がり、その中でSilverlightが読み込まれて画面が表示されます。[取得]ボタンをクリックすると、「#wp7jp」のハッシュタグがついたTwitterの発言を一覧表示します。

図1 DataGridで一覧表示の実行例
図1 DataGridで一覧表示の実行例

 次に、FlexGridを使った場合の実装方法を見ていきたいと思います。

DataGridからFlexGridへの移行

 FlexGridを使う局面としては、新規に作成する場合以外にもDataGridからの置き換え(移行)という局面もあると思います。そこで、DataGridを使ったプログラムをもとにして、FlexGridに移行する手順を確認していきます。

コンポーネントの追加

 FlexGridは標準コンポーネントではないので、IDEにコンポーネントを取り込まなければなりません。ツールボックスでアイテムの追加を行い「C1FlexGrid」を指定して、FlexGridコントロールをツールボックスに追加します。

図2 コンポーネントの追加
図2 コンポーネントの追加

FlexGridでの一覧表示画面のデザイン

 FlexGridを使用するための前準備としては、次の2つの手順が必要です。

  • 「C1.Silverlight.FlexGrid.4」に対する参照設定の追加
  • XAML定義に「xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"」を追記

 この手順は、FlexGridコントロールをツールボックスからドラッグ&ドロップすれば自動的に行われます。よって、DataGridからFlexGridに移行するときに最初に行う事は、DataGrid部分の書き換えではなく、ツールボックスからFlexGridコントロールをXAML上にドラッグ&ドロップする事です。それから、DataGridに書かれている属性をFlexGrid側のXAML定義の中にコピーして、DataGrid部分を削除します。

リスト3 DataGridをFlexGridに移行した画面デザイン例
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Orientation="Horizontal">
        <Button x:Name="Get_Button" Content="取得" Width="100" 
                Click="Get_Button_Click" />
    </StackPanel>
    <c1:C1FlexGrid Grid.Row="1"
                  AutoGenerateColumns="True" 
                  HorizontalAlignment="Left" 
                  x:Name="Result_DataGrid" 
                  VerticalAlignment="Top" 
                  Height="227" 
                  Width="500"
                  SelectionMode="RowRange">
    </c1:C1FlexGrid>
</Grid>

 XAML定義としては「sdk:DataGrid」を「c1:C1FlexGrid」に置き換え、「SelectionMode="RowRange"」の定義を追記しただけです。

FlexGridにおける一覧表示させるコード

 今回のサンプルコードでは、コード側はDataGridの場合のコードがそのまま使えるので、変更はありません。

一覧表示の実行

 XAML側とコード側が完成したら実行してみましょう。

 IDEから実行すれば自動的にWebブラウザが立ち上がり、その中でSilverlightが読み込まれて画面が表示されます。[取得]ボタンをクリックすると、「#wp7jp」のハッシュタグがついたTwitterの発言を一覧表示します。

図3 FlexGridを使った一覧表示の実行例
図3 FlexGridを使った一覧表示の実行例

 DataGridと同じような結果となりましたが、「from_user」欄の列幅が異なります。これはDataGridが該当列に表示されている情報の最大幅に、自動的に調整をしているからです。

AutoSizeColumnsを使用

 DataGridと同じ列幅を実現するためには、FlexGrid側にデータ連結した後に「AutoSizeColumns」を設定する必要があります。

リスト4 AutoSizeColumnsの設定例
Private Sub Webs_DownloadStringCompleted(sender As Object,
                                         e As DownloadStringCompletedEventArgs) _
                                     Handles Webs.DownloadStringCompleted
    Me.Get_Button.IsEnabled = True
    Me.Cursor = Cursors.Arrow
    If e.Error IsNot Nothing Then
        MessageBox.Show(e.Error.Message)
    Else
        Dim serializer As New DataContractJsonSerializer(GetType(TSearchResult))

        Using stream As New System.IO.MemoryStream(Encoding.UTF8.GetBytes(e.Result))
            Dim result As TSearchResult = CType(serializer.ReadObject(stream), 
                TSearchResult)
            Dim view As New Data.PagedCollectionView(result.results)
            Me.Result_DataGrid.ItemsSource = view
            Me.Result_DataGrid.AutoSizeColumns(0, Me.Result_DataGrid.Columns.Count - 1, 0)
        End Using
    End If
End Sub

 この設定を行えば、FlexGridでも自動的に列幅が設定されます。

図4 列幅調整後の一覧表示の実行例
図4 列幅調整後の一覧表示の実行例

FlexGridの性能を大量データの取り扱いで評価してみる

 Silverlight標準のDataGridにもFlexGridにも行方向の仮想化機能が実装されています。この機能は実際に表示されている行だけを表示処理することで、行数が増えた時でも快適なスクロールを実現する機能です。FlexGridの場合は、これに加えて列方向の仮想化も実現します。列方向の仮想化を同時に実装することで、列数が多い場合でもスクロール性能が低下しません。

 500列や1000列のデータを扱うときの性能差を、グレープシティのデモサイト(「パフォーマンス」タブ)にある、サンプルで確認してみましょう。データ設定の時間も含めて、DataGridとFlexGridでは明確な差を感じられると思います。

図5 グレープシティのデモサイトで列数を500に設定した場合の、DataGridとFlexGridの比較
図5 グレープシティのデモサイトで列数を500に設定した場合の、DataGridとFlexGridの比較

 それでは、列数が少ない場合はどうでしょうか。データが多いときのケースとしては、列方向にデータが多いのではなく、行方向にデータが多いという場合も想定できます。そこで、DataGridとFlexGridに、それぞれ100,000レコードのデータを表示した場合、スクロール表示時に差が出るかを確認してみました。

図6 DataGridとFlexGridの大量データスクロール比較例
図6 DataGridとFlexGridの大量データスクロール比較例

 それぞれスクロールボックスを上下にドラックさせてみると、FlexGridの方がスムーズにスクロールできることが分かると思います。行方向の仮想化だけであればDataGridにも実装されているのですが、同じ機能でもFlexGridの方がよりスマートな表示を実現しているのは驚きです。Silverlightのように、よりよいUIを期待して採用されるであろう技術の場合、このようなちょっとした違いが利用者の印象を左右します。

さいごに

 SilverlightのDataGridでは、何か物足りない感がありました。これは、一覧表示だけであればDataGridを使うよりも、ListBoxの中に別のコントロールを配置してデザインした方が自由度が高いデザインが作れる、というのも影響しているように思います。

 しかし、FlexGridならば、一覧表示コントロールの利便性と共にデザインの自由度もあります。業務用アプリケーションを作成するという場面では、FlexGridを使用する事で、DataGridやListBoxを使用するよりも様々な恩恵を受けられるでしょう。また、データ連結が必須ではないという手軽さもあります。そして、なによりFlexGrid for Windows Formsと近い感覚で設定ができるというのが、Windows Formsからの移行組にとっては福音となるでしょう。

製品情報

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5866 2011/04/12 14:00

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング