ItemsControlのItemsプロパティには直接Stringを設定すべきではない

ListBoxのItems.Addで文字を直接入力した時のセレクトがおかしくなる - MSDN フォーラム

上記のMSDNフォーラムの内容を試してみたところ、ItemsControlのItemsプロパティには直接Stringを設定すべきではないということが分かりましたので、その内容について紹介したいと思います。

MSDNライブラリ ItemsControl型 コンテンツモデルの概要

上記のMSDNライブラリに記載があるようにItemsControlはコンテンツの種類として文字列とオブジェクト(UIElement)をサポートしています。つまり、コンテンツとして直接System.Stringオブジェクトを持つことができるわけです。しかしながら、Stringを直接設定した場合、いくつか問題が発生します。


質問者の方は「セレクトがおかしくなる」と表現されていますが、具体的には下記のような現象が発生します。
XAML

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:System="clr-namespace:System;assembly=mscorlib"
   x:Class="UntitledProject1.Window1"
    Title="SlectorControls" Width="400" Height="300">
 
    <StackPanel x:Name="LayoutRoot">
        <ListBox Margin="10">
            <System:String>string</System:String>
            <System:String>string</System:String>
            <System:String>string</System:String>
            <ListBoxItem Content="ListBoxItem"/>
            <ListBoxItem Content="ListBoxItem"/>
            <ListBoxItem Content="ListBoxItem"/>
        </ListBox>
        <ComboBox Margin="10">
            <System:String>string</System:String>
            <System:String>string</System:String>
            <System:String>string</System:String>
            <ComboBoxItem Content="ComboBoxItem"/>
            <ComboBoxItem Content="ComboBoxItem"/>
            <ComboBoxItem Content="ComboBoxItem"/>
        </ComboBox>
        <TabControl Margin="10">
            <System:String>string</System:String>
            <System:String>string</System:String>
            <System:String>string</System:String>
            <TabItem Header="TabItem" Content="TabItem"/>
            <TabItem Header="TabItem" Content="TabItem"/>
            <TabItem Header="TabItem" Content="TabItem"/>
        </TabControl>
    </StackPanel>
</Window>





上記のサンプルは、Selectorの派生クラスであるListBox、ComboBox、TabConrolについてStringオブジェクトと各コントロールの既定のアイテムコンテナを設定したものです。画面のスクリーンショットを見ていただくと分かる通り、ListBoxとTabConrolについては複数のStringアイテムが選択されたままの状態になっています。もちろんListBoxのSelectionModeプロパティは設定していないので、既定値であるSingleです。


また、ComboBoxについてはドロップダウンを表示した時点でリストの選択はいったん解除されるので特に問題ないように見えますが、選択をキーボードの上下キーで遷移させるとStringアイテムに差し掛かったタイミングで遷移しなくなってしまうという問題がやはりあります。


なお、HeaderedItemsControlの派生クラスであるMenuItemなどでもこれと同じ現象が発生するようです。


XAMLでこのように書く人はほとんどいないかもしれませんが、コードからアイテムを追加する場合などは直接Stringを格納してしまうこともあると思いますので、気をつけたほうが良いですね。


追記
ちなみに、下記のようにStringの文字列がそれぞれ違う場合には、上記の問題は発生しません。
XAML
<System:String>string1</System:String>
<System:String>string2</System:String>
<System:String>string3</System:String>


これはつまり、同じ文字列だと完全に同じオブジェクトとなってしまい異なるアイテムだと判別できないということが問題の原因ではないかと推測されます。