MetroStyleApp入門 vol48.コントロールのテンプレートを動的に切り替える

土曜日 , 18, 8月 2012 Leave a comment

 例えばListViewやGridViewの背景色を表示するアイテム別に変更したいというケースがあると思います。

 そのような場合の解決方法紹介します。

 

DataTemplateSelector

 

 ListViewなどのコレクションの定義はDataTemplateで行います。

 DetaTemplateについては「MetroStyleApp入門 vol.21 GridView」やWindows Phoneを対象としていますが「WindowsPhone] ListBoxItemのスタイルを編集する」で触れました。

 

 そのDataTemplateを動的に切り替える仕組みがDataTemplateSelectorクラスです。

 

 今回のコードは以下、

 

    /// <summary>
    /// 一つおきに異なるテンプレートを適用するサンプル
    /// </summary>
    class Selector : DataTemplateSelector
    {
        public int i = 0;

        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            i++;

            if (i % 2 == 0)
            {
                return (DataTemplate)Application.Current.Resources["DataTemplate1"];
            }
            else
            {
                return (DataTemplate)Application.Current.Resources["DataTemplate2"];
            }
        }
    }

 

 変数のiが偶数か奇数かどうかで返すDataTemplateを変えています。

 これがテンプレートを変更してアイテムの見た目を変える仕組みです。

 

Application.Current.Resources

 

 Application.Current.Resourcesからキーを指定してDataTemplateを取得しています。

 DataTemplateの定義はCommon.StandardStyles.xamlで行います。

 (App.xamlで読み込まれているので、共通のリソースとして呼び出せる)

 

 DataTemplate1とDataTemplate2は以下のように定義してあります。

 

    <DataTemplate x:Key="DataTemplate1">
        <Grid Background="#FF0046FF">
            <TextBox TextWrapping="Wrap" Text="{Binding text}" Foreground="#FF080280"/>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate2">
        <Grid>
            <TextBox TextWrapping="Wrap" Text="{Binding text}" Background="#FF0760CB" Foreground="#FFB4CCF5"/>
        </Grid>
    </DataTemplate>

 

 続いて、ListView側でDataTemplateSelectorをどのように利用するか見てみましょう。

 

Resourcesとして読み込む

 

 XAML側でC#のクラスを利用したい場合はResourceとして定義してあげます。

 以下のようなディレクトリ構成でSelector.csが配置されている場合、

 

<a href="http://coelacanth.heteml.jp/blog/wp-content/uploads/2012/08/00116.png"><img class="alignnone size-medium wp-image-1791" title="001" src="http://coelacanth.heteml.jp/blog/wp-content/uploads/2012/08/00116-300x244.png" alt="" width="300" height="244" /></a>

<Page
    x:Class="DataTemplateSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DataTemplateSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
	<Page.Resources>
        <local:Selector x:Key="Selector" />
    </Page.Resources>

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

 

 このようにResourcesにSelectorクラスを登録します。

 x:KeyはこのXAMLの中でSelectorクラスを使うための識別子なので任意の名前で構いません。

 

ListViewのItemTemplateSelecterに指定

 

 最後にSelectorクラスをListViewのItemTemplateSelecterに指定してあげます。

 

        <ListView HorizontalAlignment="Stretch" Height="717" Margin="27,22,0,0" VerticalAlignment="Top" Width="800"
                  ItemsSource="{Binding}"
                  ItemTemplateSelector="{StaticResource Selector}"
                  HorizontalContentAlignment="Stretch"
        >
	</ListView>

 

 以下のようにC#コード側でDataTemplateにアイテムを追加します。

 

namespace DataTemplateSample
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            this.DataContext = new List<Data>() { new Data() { text = "test" }, new Data() { text = "test2" }, new Data() { text = "test3" }, new Data() { text = "test4" } }; 
        }

        /// <summary>
        /// このページがフレームに表示されるときに呼び出されます。
        /// </summary>
        /// <param name="e">このページにどのように到達したかを説明するイベント データ。Parameter 
        /// プロパティは、通常、ページを構成するために使用します。</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }
    }

    public class Data
    {
        public string text { get; set; }
    }
}

 

実行すると以下のように一つおきに背景画像が違うリストが表示されました。


Please give us your valuable comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください