トルネード

毛利のメモ書き

UWP 入門 - SemanticZoom

SemanticZoomとは

UWPでの、SemanticZoomとは、グループ化されたデータセットを2つの異なるビュー切替えナビゲートできるコントロールです。

  • ZoomedInView はコンテンツのメインビューで、個々のデータ項目を表示する。
  • ZoomedOutView は、 このビューにグループ化されたデータセットのグループヘッダーを表示します。

例えば、アドレス帳を見るとき、ユーザズームアウトして文字「W」に素早くジャンプし、その文字を拡大してそれに関連する名前を見ることができる。

グループヘッダーアイテム型

SemanticZoomを使う場合最初にグループとアイテムの型を作っておく必要があります。ここでは図のようにシンプルクラスを作成します。

f:id:mojeld:20180806123252p:plain

TGroupはグループのヘッダーになる型です。TRowObjectはアイテムです。

public class TRowObject
{
    public string ItemName { get; private set; }
    public string Value { get; private set; }
    public TRowObject(string s1, string s2)
    {
        this.ItemName = s1;
        this.Value = s2;
    }
}
public class TGroup
{
    public TGroup(string lg1)
    {
        this.GName = lg1;
        Items = new ObservableCollection<TRowObject> {};
    }
    public ObservableCollection<TRowObject> Items { get; }
    public string GName { get; private set; }
    public override string ToString()
    {
        return this.GName;
    }
}

XAML側の処理

Page.Resources側にグループ用とアイテム用/グループヘッダー用3つのDataTemplateを作ります。実データと紐づけるだめの、CollectionViewSourceも作成します。 メイン部分にはSemanticZoomを配置し、ZoomedInViewにはグループとアイテムを表示するためのGridViewと、ZoomedOutViewにはグループ一覧を表示するためのListViewを配置します。

f:id:mojeld:20180806125345p:plain

Page.Resources側 コード

<Page.Resources>
    <CollectionViewSource x:Name="CollectionViewSource1" Source="{x:Bind G1}" IsSourceGrouped="True" ItemsPath="Items"/>
    <DataTemplate x:Key="ZoomedInGroupHeaderTemplate" x:DataType="data:TGroup">
        <TextBlock Text="{x:Bind GName}" Foreground="LightBlue" Style="{StaticResource SubtitleTextBlockStyle}"/>
    </DataTemplate>
    <DataTemplate x:Key="ZoomedInTemplate" x:DataType="data:TRowObject">
        <StackPanel Orientation="Vertical" MinWidth="200" Margin="12,6,12,6">
            <TextBlock Text="{x:Bind ItemName}" TextWrapping="Wrap" HorizontalAlignment="Left" Width="300" Style="{StaticResource BodyTextBlockStyle}" Foreground="LightPink" />
            <TextBox Text="{x:Bind Value}" TextWrapping="Wrap" HorizontalAlignment="Left" Width="300" Style="{StaticResource AutoSuggestBoxTextBoxStyle}" Foreground="LightCoral" />
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="ZoomedOutTemplate" x:DataType="wuxdata:ICollectionViewGroup">
        <TextBlock Text="{x:Bind Group.(data:TGroup.GName)}" Style="{StaticResource SubtitleTextBlockStyle}" TextWrapping="Wrap"/>
    </DataTemplate>
</Page.Resources>

メイン部分の XAMLコード

<SemanticZoom HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Top" IsZoomedInViewActive="True" Grid.Row="1">
    <SemanticZoom.ZoomedOutView>
        <ListView ItemsSource="{x:Bind CollectionViewSource1.View.CollectionGroups}" SelectionMode="None" ItemTemplate="{StaticResource ZoomedOutTemplate}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" Background="LightCoral" Opacity="0.8"/>
    </SemanticZoom.ZoomedOutView>
    <SemanticZoom.ZoomedInView>
        <GridView ItemsSource="{x:Bind CollectionViewSource1.View}" ScrollViewer.IsHorizontalScrollChainingEnabled="False" SelectionMode="None" ItemTemplate="{StaticResource ZoomedInTemplate}">
            <GridView.GroupStyle>
                <GroupStyle HeaderTemplate="{StaticResource ZoomedInGroupHeaderTemplate}" />
            </GridView.GroupStyle>
        </GridView>
    </SemanticZoom.ZoomedInView>
</SemanticZoom>

データを作成する

型の指定はできたので、インスタンスを作成しデータを適当に埋めていくコードを書きます。

public sealed partial class BlankPage1 : Page
{
    public IList<TGroup> G1 { get; private set; }

    public BlankPage1()
    {
        this.InitializeComponent();
        this.G1 = new List<TGroup>();
        for (int i = 0; i < 10; ++i)
        {
            G1.Add(new TGroup(string.Format("グループ{0}", i)));
            for (int i2 = 0; i2 < 5; ++i2)
            {
                G1[i].Items.Add(new TRowObject(string.Format("アイテム{0}", i2), string.Format("ヴァリュー{0}", i2)));
            }
        }
    }
}

コンストラクタ側で先にデータを作成する。

実行画面

ZoomedInViewZoomedOutView のグループが連動していることが確認できます。

f:id:mojeld:20180806130231g:plain