2011年1月6日木曜日

Canvasにリストの中身をBindingする方法

ObservableCollectionでもなんでもいいのだが、リストで保持している内容をCanvasに表示したいことはままある。しかしCanvas.Childrenに対して単純にBindingしても予期した動作にはならない。そんな場合はItemsControlのItemsPanelTemplateを使用する。

こんな風にデータをCanvas上に表示したい。

public ObservableCollection<TextData> TextList { get; set; }
TextList = new ObservableCollection<TextData>(
                new List<TextData>
                {
                    new TextData{ Left=110, Top=110, Text="嘘だと" },
                    new TextData{ Left=210, Top=210, Text="言ってよ" },
                    new TextData{ Left=310, Top=310, Text="バーニィ" },
                });
各TextDataクラスはLeft, TopでCanvas上の位置を保持している。

では、上記のリストをCanvas上に配置するためのXamlを見てみよう。
<ItemsControl ItemsSource="{Binding Path=TextList}"
                      VerticalAlignment="Stretch"
                      HorizontalAlignment="Stretch">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Text}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Canvas.Top" Value="{Binding Path=Top}" />
                    <Setter Property="Canvas.Left" Value="{Binding Path=Left}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>
ポイントはItemsControl.ItemsPanelのItemsPanelTemplateを使用している箇所。そこでアイテム配置用のパネルにCanvasを指定しているので、下のほうのItemsControl.ItemContainerStyleで各アイテムのLeft, Topを指定して任意の位置にデータを表示させることが可能となる。

サンプルコードはこちら。
(Chromeだと下記iframeが表示されない模様。FireFoxでは表示確認済み)

0 件のコメント:

コメントを投稿