困りました。ItemsControlにFrameworkElementを並べたらItemTemplateが反映されず、FrameworkElement自身がUIに表示されてしまします。
<ItemsControl Margin="12" MaxHeight="160"> <ItemsControl.ItemTemplate> <DataTemplate> <Border BorderBrush="SpringGreen" BorderThickness="1"> <Button Content="aaa" /> </Border> </DataTemplate> </ItemsControl.ItemTemplate> <Rectangle Height="10" Fill="Tomato"/> <Rectangle Height="10" Fill="MediumTurquoise"/> <Rectangle Height="10" Fill="YellowGreen"/> </ItemsControl>
これの結果がこれです。
ちなみにListBoxでは期待したとおりにDataTemplateが反映されます。
<ListBox Margin="12" MaxHeight="160"> <ItemsControl.ItemTemplate> <DataTemplate> <Border BorderBrush="SpringGreen" BorderThickness="1"> <Button Content="aaa" /> </Border> </DataTemplate> </ItemsControl.ItemTemplate> <Rectangle Height="10" Fill="Tomato"/> <Rectangle Height="10" Fill="MediumTurquoise"/> <Rectangle Height="10" Fill="YellowGreen"/> </ListBox>
調べたところ、ItemsControlはItemがUI要素かどうかでItemsControl.IsItemItsOwnContainerOverrideの値をtrue or false に切り替えているようです。おそらくListBoxはfalse 決め打ちっぽいです。まぁ確かに前者のほうが挙動としては正のでしょうが…
ここを常にfalse を返すようにしたItemsControlの派生クラスを作ってみました。
public class HogeItems : ItemsControl { protected override bool IsItemItsOwnContainerOverride(object item) { return false; } }
<local:HogeItems Margin="12" MaxHeight="160"> <ItemsControl.ItemTemplate> <DataTemplate> <Border BorderBrush="SpringGreen" BorderThickness="1"> <Button Content="aaa" /> </Border> </DataTemplate> </ItemsControl.ItemTemplate> <Rectangle Height="10" Fill="Tomato"/> <Rectangle Height="10" Fill="MediumTurquoise"/> <Rectangle Height="10" Fill="YellowGreen"/> </local:HogeItems>
期待通りの結果になりました。