コンボボックスでいくつかの問題が発生したため、これを見始めました。残念ながら、私は問題を解決していませんが、この問題に対する追加の洞察と回避策を提供できます。まず、元の xaml への変更から始めましょう。
<TabControl Height="100" Name="TabControl1" Width="220">
<TabItem Header="TabItem1" x:Name="TabItem1">
<TextBlock Text="TabItem1 Content" />
</TabItem>
<TabItem Header="TabItem2" x:Name="TabItem2">
<TextBlock Text="TabItem2 Content" />
</TabItem>
</TabControl>
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
DisplayMemberPath="Name"
>
</ComboBox>
タブ コントロールから ComboBox へ、またはその逆のバインディングを作成する代わりに、タブ コントロールとコンボ コントロールの SelectedIndex の間に TwoWay バインディング (この場合のデフォルト) を作成できることに注意してください。次に、TabItems にコンテンツを追加しましょう。この時点で、Steve の提案と同様に、「制御」の問題を修正しました。つまり、選択された TabItem を変更すると、選択された ComboBox アイテムが変更され (これについて私を信頼するか、読み続ける必要があります!)、ComboBox を変更すると、選択された TabItem が変更されます。すごい!
上記の xaml は、DiplayMemberPath プロパティも "Name" に変更します。これにより、huhdbrown の「奇妙な結果」が解消されることがわかると思います。Header プロパティ (オブジェクト) が ContentPresenter によってラップされていることを思い出してください。テンプレートが提供されていない場合、デフォルトの動作は Header オブジェクトを TextBlock の文字列として表示することだと思います。したがって、「奇妙な結果」は、TextBlock コントロールに Header プロパティが含まれていないことを正しく報告します。
ここで、前の ComboBox xaml に変更を加えてみましょう。
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
これは実際に興味深い結果を生成し、各 TabItem に追加したコンテンツを利用します。このコードを実行すると、選択した TabItem のコンテンツが ComboBox に表示されることがわかります。さらに、リストには、TabItem ごとに "System.Windows.Controls.TabItem..." が表示されるようになりました。TextBlock バインディングを {Binding Header} に変更して Header オブジェクトを表示できますが、ComboBox には選択した TabItem のコンテンツが引き続き表示されます。金曜日の夜遅く、世界にはビールが十分にないため、考えられる理由を調べませんでした. ただし、回避策があります。
まず、TabControl の Items コレクションを使用できるものに変換する ValueConverter を作成しましょう。これがコードです。
public class TabItemCollectionConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ItemCollection collection = value as ItemCollection;
IList<string> names = new List<string>();
foreach (TabItem ti in collection.SourceCollection)
{
names.Add(ti.Header.ToString());
}
return names;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
コンバーターは、各 TabItem の文字列化された Header オブジェクトを含む TabControl の Items コレクションから新しいコレクションを作成するだけです。これは、単純な Header オブジェクトでは問題なく機能しますが、明らかに制限があります。これを xaml でどのように使用するかを考えてみましょう。
<ComboBox Height="23" Name="CmbTabs" Width="120"
ItemsSource="{Binding ElementName=TabControl1, Path=Items, Converter={StaticResource ItemConverter}}"
SelectedIndex="{Binding ElementName=TabControl1, Path=SelectedIndex}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
ItemsSource バインディングで使用される ValueConverter は新しいコレクションを返すことに注意してください。この場合、TabControl の Items コレクションを文字列コレクションに変換しています。コンバータ StaticResource を作成することを忘れないでください! こんな感じです。
<local:TabItemCollectionConverter x:Key="ItemConverter"/>
コンバーターを使用すると、ワックスのボール全体が期待どおりに機能します。
まだ困惑しているのは、ComboBox がリストに TabItem ヘッダーを表示し、TabItem コンテンツを選択として表示する理由です。明らかな説明があることは間違いありませんが、私が言ったように、それは金曜日です...
お役に立てれば!