SHOEISHA iD

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

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

Infragistics NetAdvantageチュートリアル(AD)

Silverlightでのツリー表示(その2): 標準TreeViewコントロールとNetAdvantage XamDataTreeコントロール - UI カスタマイズ編

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

DataTemplate

 Templateプロパティ、ItemTemplateプロパティ、HierarchicalDataTemplateプロパティに設定できるテンプレートはControlTemplateの他にDataTemplateがあります。

 DataTemplateはContentControl、ItemsControlなどのコントロールに指定された特定オブジェクトのデータ型に合わせたUI表現を定義することができるTemplateになります。

 DataTemplateの代表的な利用方法の一つとしてItemsControlのItemTemplateプロパティに定義するシナリオがあります。

 これまでご説明したようにItemsControlは任意データのコレクションを指定することができます。DataTemplateを使うとこれらのコレクションの個々のオブジェクトに合わせて表示をカスタマイズできます。

 ItemsControlでは実際にItemsSourceに適用されたコレクション内の各オブジェクトはDataTemplateを使って表示用のオブジェクトツリーを作成します。これを表示ツリーと呼びます。

 表示ツリー作成されると、最終的にはテンプレート適用先のコントロールが持つDataContextプロパティにコレクションの個々のオブジェクトが設定されます。

 例えばTreeViewコントロールの場合、生成されるコントロールがTreeViewItemコントロールとなるので、最終的にはこのコントロールのTemplateプロパティDataTemplateが設定され、そしてTreeViewItemコントロールのDataContextプロパティに対して個々のオブジェクトが設定されます。

 Bindingは明確なソースの指定がされていなければコントロールのDataContextプロパティを参照するため、DataTemplate内ではBindingを利用して個々のオブジェクトへのプロパティパスを定義することで、表示に反映させることが可能です。

 それでは、ここまでItemsControlの説明をまとめると以下のようなイメージになります。

 それでは、サンプルにTreeViewコントロールのItemTemplateにDataTemplateを設定してみましょう。

 まず、データ表示を行う簡単なエンティティクラス、Personクラス定義から行いましょう。

 メンバーはstring型のNameプロパティ、int型のAgeプロパティを実装しておきます。

List4 Personクラス[C#]
public class Person : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; RaisePropertyChanged(Name); }
    }

    private int _age;
    public int Age
    {
        get { return _age; }
        set { _age = value; RaisePropertyChanged("Age"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

 続けて、TreeViewコントロールのItemTemplateに対してPersonクラスに合わせたDataTemplateを作成します。

List5 ItemTemplateにDataTemplateを設定[XAML]
<sdk:TreeView Name="treeView1">
    <sdk:TreeView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Width="100" />
                <ProgressBar Minimum="0" Maximum="150" Value="{Binding Age}" Width="400" />
            </StackPanel>
        </DataTemplate>
    </sdk:TreeView.ItemTemplate>
</sdk:TreeView>

 そして、UserControlのLoadedイベントでサンプルデータをセットします。

List6 DataTemplateの確認用サンプルデータをセット[C#]
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    treeView1.ItemsSource = new ObservableCollection<Person>()
                                {
                                    new Person() { Name = "しるば太郎", Age = 40},
                                    new Person() { Name = "しるば次郎", Age = 35},
                                    new Person() { Name = "しるば子太郎", Age = 15},
                                    new Person() { Name = "しるば親次郎", Age = 60},
                                    new Person() { Name = "しるば孫太郎", Age = 5}
                                };
}

 実行結果は以下のとおりです。

 今回利用したコントロールはTreeViewコントロールですが、データが階層構造でないことや、DataTemplateを指定したことで本来のTreeViewコントロールで表示されていた階層構造などは表現されていません。

 階層構造を指定する場合は、HierarchicalDataTemplateというテンプレートを利用します。

HierarchicalDataTemplate

 TreeViewコントロールで、階層構造を使った表現をカスタマイズする場合はHeaderedItemsControlに特化したDataTemplate、HierarchicalDataTemplateを使用することで実現できます。

 このテンプレートをItemTemplateに定義することで階層構造の表示方法をカスタマイズできます。

 HierarchicalDataTemplateはTemplate自体にさらにItemsSource, ItemsContainerStyle, ItemTemplateを指定することで、ヘッダー表示用のTemplate、そしてコレクション表示用のTemplateを指定することができます。

 TreeViewコントロールでは、このItemTemplateにHierarchicalDataTemplateを指定することで、階層構造を展開できるような仕組みを提供しています。

 それでは実際にHierarchicalDataTemplateを使ってTreeViewコントロールをカスタマイズしてみましょう。

 まずは先ほどと同様、エンティティクラスの定義から。 先ほどのPersonクラスを少し拡張して、家族データを保持するための下記のようにFamilyプロパティを追加します。

List7 Familyプロパティを追加[C#]
private ObservableCollection<Person> _family = new ObservableCollection<Person>();
public ObservableCollection<Person> Family { get { return _family;  } }

 続けてHierarchicalDataTemplateを定義し、TreeViewコントロールのItemTemplateに設定します。

List8 HierarchicalDataTemplateで2階層のテンプレートを設定[XAML]
<UserControl x:Class="_03_HierarchicalDataTemplate.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400" 
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    Loaded="UserControl_Loaded">
    <UserControl.Resources>
        <sdk:HierarchicalDataTemplate x:Key="FamilyTemplate">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Width="100" />
                <ProgressBar Minimum="0" Maximum="150" Value="{Binding Age}" Width="400"  />
            </StackPanel>
        </sdk:HierarchicalDataTemplate>
        <sdk:HierarchicalDataTemplate x:Key="DetailTemplate"
                                      ItemsSource="{Binding Family}"
                                      ItemTemplate="{StaticResource FamilyTemplate}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Width="100" />
                <ProgressBar Minimum="0" Maximum="100" Value="{Binding Age}" Width="400"  />
            </StackPanel>
        </sdk:HierarchicalDataTemplate>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White">
        <sdk:TreeView Name="treeView1" ItemTemplate="{StaticResource DetailTemplate}" />
    </Grid>
</UserControl>

 そして、UserControlのLoadedイベントでサンプルデータをセットします。

List9 HierarchicalDataTempplate用のサンプルデータを設定[C#]
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    treeView1.ItemsSource = new ObservableCollection<Person>()
                                {
                                    new Person() { Name = "しるば太郎", Age = 40},
                                    new Person() { 
                                        Name = "しるば次郎", 
                                        Age = 35,
                                        Family =
                                            {
                                                new Person() { Name = "しるば兄太郎", Age = 25},
                                                new Person() { Name = "しるば弟太郎", Age = 20},
                                            }

                                        },
                                    new Person() { Name = "しるば三郎", Age = 60},
                                };
}

 実行結果は以下のとおりです。

次のページ
XamDataTreeのカスタマイズ

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

  • このエントリーをはてなブックマークに追加
Infragistics NetAdvantageチュートリアル連載記事一覧

もっと読む

この記事の著者

森 博之(AZPower株式会社)(モリ ヒロユキ)

 Microsoft Azure、.NETテクノロジーを使用したWebサービスのプロダクトアーキテクト。他にも技術記事の執筆やトレーニング、セミナースピーカーを行っている。 Microsoft MVPをDeveloper Technologies、Visual Studio and Development Technologies、Windows Development、Client App Dev、.NET、Silverlight、Visual C#などのコン...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング