CakePHPのXMLレスポンスをListViewで一覧表示する

CakePHPのXMLレスポンスをストアアプリで一覧表示する | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/5374

の ListView 版です。GridView の場合、横スクロールなのですが、ListView は縦スクロール。WPF の ListView と同じ感じ…では使えないので結構面倒です。なので、フォームにあるリストビューを作りたい場合は下手に自作するよりもコンポーネントを買ったほうがいいような気がするのですが。Windows UI http://jp.infragistics.com/products/windows-UI.aspx のグリッドコントロールじゃないですかね。

が、あえて自作します。

こんな風にフォームアプリのように縦スクロール。右側にそれぞれの値を表示という画面です。
まず、標準で「これじゃない感」が強いので、このままでは役に立たないのです。これじゃないところを列挙すると、

  • 縦スクロールすると、タイトル部分もスクロールしてしまう。
  • 幅をユーザーが自由に変えられない。

ちなみに、業務のほうは、ヘッダ部分を ListView の外側に追いやって逃れました。ヘッダクリックでのソートと幅の変更は WPF の ListView には備わっているのですが、WinRT のほうにはありません。というか、まったく別物です。

データモデルは同じなので、リストビューを作るところから。

■リストビューを作る

<ListView 
    ItemsSource="{Binding Items}"
    d:DataContext="{d:DesignData /SampleData/StoreSampleData.xaml}"
    HeaderTemplate="{StaticResource myHeaderTemplate}"
    ItemTemplate="{StaticResource myItemTemplate}"
    SelectionChanged="ListView_SelectionChanged"
    Margin="10" Grid.Row="1">
</ListView>

リストビューにはヘッダ部分(HeaderTemplate)とアイテム部分(ItemTemplate)のテンプレートを指定できるのですが、ヘッダ部分もスクロールしてしまうんですよね…というか、どうやらアイテムの先頭だけを「ヘッダ」と言っているようです。英文の最初の文字を大きくするイメージでしょうか。日本のエクセル方眼紙にはなじめない文化ですよね、とか。

リソースは ListViewHeaderItem と ListViewItem の2つを作っておきます。ヘッダ部分の Text プロパティは直書きに、アイテムのほうはバインドしているのですが、これはフォームアプリのデータグリッドのように両方いっぺんにバインドをしたいところです。

    <DataTemplate x:Key="myHeaderTemplate">
        <Grid 
        Background="ForestGreen"
        Margin="1" Height="50" 
        >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="ID" FontSize="32" Grid.Column="0" />
            <TextBlock Text="Store" FontSize="32" Grid.Column="1" />
            <TextBlock Text="Sellingcompany" FontSize="32" Grid.Column="2" />
            <TextBlock Text="Areagroup" FontSize="32" Grid.Column="3" />
            <TextBlock Text="modified" FontSize="32" Grid.Column="4" />
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="myItemTemplate">
        <Grid 
                    Background="BlueViolet"
                    Margin="1" Height="50" Width="1030"
                    >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding ID}" FontSize="32" Grid.Column="0" />
            <TextBlock Text="{Binding Name}" FontSize="32" Grid.Column="1" />
            <TextBlock Text="{Binding Sellingcompany.Name}" FontSize="32" Grid.Column="2" />
            <TextBlock Text="{Binding Areagroup.Name}" FontSize="32" Grid.Column="3" />
            <TextBlock Text="{Binding modified}" FontSize="32" Grid.Column="4" />
        </Grid>
    </DataTemplate>

ColumnDefinition で等倍にしていますが、本来ならばサイズを指定したいところです。というか、自動的にサイズを計算してほしいところですね。このあたりの機能はあるかないか分かりません(たぶん無い)。1画面だけ作るのであれば、これでいいのですがマスター画面で十数画面を一気に作ろうと思うと結構面倒くさいことになります。まあ、マスター画面自体を「没入型」で作るかどうかは別だし。

■プロパティビューっぽいものとバインド用のモデル

プロパティビューのところは、GridView と同じです。ふつうにバインドしていけばOK。バインド用のモデルクラスも同じ。

■アイテムを選択したときのイベント

/// <summary>
/// アイテムを選択したとき
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var item = e.AddedItems[0] as Model.Store;
    _model.Item = item;
}

やっていることは、「分割ページ」の ListView と同じなんですけどね。

■方眼紙っぽく枠線をつけてみる

縦横の線を書く、ってことはできなそうなので、まめに boarder をつけます。何気に面倒ですが、以下のように Border をちまちまつけていくと枠線が引けます…が、こんなことやるぐらいだったらコードで自動生成したいですよね。

<DataTemplate x:Key="myItemBTemplate">
    <Grid 
                Background="BlueViolet"
                Margin="1" Height="50" Width="1030"
                >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <Border BorderBrush="White" BorderThickness="2" Padding="3" Grid.Column="0" >
            <TextBlock Text="{Binding ID}" FontSize="32" />
        </Border>
        <Border BorderBrush="White" BorderThickness="2" Padding="3" Grid.Column="1" >
            <TextBlock Text="{Binding Name}" FontSize="32" />
        </Border>
        <Border BorderBrush="White" BorderThickness="2" Padding="3" Grid.Column="2" >
            <TextBlock Text="{Binding Sellingcompany.Name}" FontSize="32" />
        </Border>
        <Border BorderBrush="White" BorderThickness="2" Padding="3" Grid.Column="3" >
            <TextBlock Text="{Binding Areagroup.Name}" FontSize="32" />
        </Border>
        <Border BorderBrush="White" BorderThickness="2" Padding="3" Grid.Column="4" >
            <TextBlock Text="{Binding modified}" FontSize="32" />
        </Border>
    </Grid>
</DataTemplate>

罫線としてはいまいちだし、ヘッダ部分をクリックしたらソートしてほしいし、そのあたりも含めて ListView の自動生成機能が欲しいところです。

カテゴリー: CakePHP, WPF, WinRT パーマリンク