Neutral Scent

App developments & Gadgets

ListBoxのDataTemplateの中で要素を横幅いっぱいにStretchして表示する

何度もやっているのですが、いつも忘れるので備忘録として。
Windows Phone 7Silverlightアプリでちょっと見た目に凝ったListBoxを作ろうとするとItemTemplateとDataTemplateを使用してテンプレートを定義していくのはもうお馴染みだと思います。
で、何気なくやっていると特に害が無いのですが、リストアイテムを横幅いっぱいに表示しようとすると、短いアイテムの所であれっ? ってことになりがちです。ようするにこんな感じ。

ソースはこういう感じで...、
(手書きXAML派なのでインラインテンプレートですいません、まー基本は同じです)



<Grid x:Name="LayoutRoot">
<ListBox ItemsSource="{Binding entries}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="TemplateRoot">
<TextBlock Text="{Binding Title}" FontSize="22" />
<TextBlock Text="{Binding BookmarkCount}" HorizontalAlignment="Right" Opacity="0.3" FontSize="64" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
問題は、DataTemplateから作られるListBoxItemのWidthを適当にMeasureして、TextBlockが小さいんだから、全体も小さくていいじゃない、と勝手に幅を調整してしまうことです。TemplateRoot(Grid)のWidthを固定値で回避することもできますが、それも非常に泥臭い。HorizontalAlignment="Stretch"とか付けてみても効きません。
WPFの場合はListBoxにHorizontalContentAlignment="Stretch"付ければOkよ、という話なんですが、Silverlight/WPでは何も変わりません。で、どうするかというと...

<Grid x:Name="LayoutRoot">
<Grid.Resources>
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</Grid.Resources>

<ListBox ItemsSource="{Binding entries}" ItemContainerStyle="{StaticResource ListBoxItemStyle}" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="TemplateRoot">
<TextBlock Text="{Binding Title}" FontSize="22" />
<TextBlock Text="{Binding BookmarkCount}" HorizontalAlignment="Right" Opacity="0.3" FontSize="64" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
StyleでListBoxItemにHorizontalContentAlignmentを指定してやって、そのスタイルをListBoxのItemContainerStyleに適用してやれば...

という感じにでOkに。
なんでそんな遠回りな...、と思わなくもないですが、とりあえずはこれがたぶん一番すっきりしたやり方、ということで。

プログラミング WINDOWS PHONE (MSDNプログラミングシリーズ)

プログラミング WINDOWS PHONE (MSDNプログラミングシリーズ)