多くのプロジェクトでは、複数のコンボ ボックス(選択リスト)を作成する必要が生じる場合があります。この場合、最初のコンボ ボックスの選択内容に応じて、次のコンボ ボックスの内容が決まります。最初のボックスで値が選択された時点で、次のボックスには最初の選択内容に基づいて値を表示する必要があります。たとえば、コンボ ボックスが 2 つあり、最初のコンボ ボックスには自動車のメーカー名(BMW、Mercedes、Ferrari など)を表示し、2 番目のボックスには選択したメーカーに基づいた車種(BMW の場合は 1、2、5、X2、X5 など、Mercedes の場合は A、B、C、CL、CLS など)を表示する場合を例に説明します。
各コンボ ボックスのデータを用意するには、データの取得元となるソースが必要です。ネイティブの XML エンジンには WPF が付属しているため、データを格納する XML ファイルを作成することができます。XML ファイルには、最初に選択する第 1 レベルのコンテンツが記述します。すべてのエントリには、2 番目に選択する子エントリを記述します。第 3 レベル以上のネストされた選択リストが必要な場合は、2 番目のエントリに複数の子を記述することができます。記述内容の例を次に示します。
data.xml ファイルを作成し、このコンテンツをファイルにコピーします。このファイルは、カスケード コンボ ボックスを追加する .xaml ファイルの近くに保存します(例: C:¥ProgramData¥Autodesk¥Vault <リリース年>¥Extensions¥DataStandard¥Vault¥Configuration)。
<XmlDataProvider x:Key="comboDataSource" Source="C:\ProgramData\Autodesk\Vault 2015\Extensions\DataStandard\Vault\Configuration\data.xml"/>
<prop:dsWindow.Resources xmlns:prop="clr-namespace:dataStandard.UI.View;assembly=dataStandard.UI"> ... ...... .... <XmlDataProvider x:Key="comboDataSource" Source="C:\ProgramData\Autodesk\Vault 2015\Extensions\DataStandard\Vault\Configuration\data.xml"/> </prop:dsWindow.Resources>
上で示したように、新しいリソースには comboDataSource という名前を指定し、パスは data.xml を参照するよう設定しています。
<ComboBox x:Name="ComboCarCompanies" Grid.Column="1" Grid.Row="5" ItemsSource="{Binding Source={StaticResource comboDataSource}, XPath=/Data/Companies/*}" Text="{Binding Prop[CarVendor].Value}" DisplayMemberPath="@Name" SelectedValue="{Binding Prop[CarVendor].Value}" SelectedValuePath="@Name" />
この例では、コンボ ボックスは ComboCarCompanies という名前を指定し、列 1 および行 5 に配置します。このコンボ ボックスのコンテンツのソースは、comboDataSource という名前のリソースから取得します。XPath は、コンテンツを読み込むための適切なパスを参照するように設定します。すべてを要素 Companies の下位に記述します。要素 Companies の子には、それぞれ Name というメンバーが 1 つあります。したがって、DisplayMemberPath 属性と SelectedValuePath 属性は、どちらも @Name を参照します。また、Text 属性と SelectedValue 属性は、ユーザが選択した値が入力されるプロパティを参照します。
2 番目のコンボ ボックスも、最初のコンボ ボックスと基本的に同じです。ただ、データ ソースを最初のコンボ ボックスから取得する点が唯一の相違点です。ユーザが XML ファイルのノードを 1 つ選択すると、このノードが最初のコンボ ボックスで選択されたアイテムとしてロードされます。また、このノードは選択内容の子も認識しています。
<ComboBox x:Name="ComboCarType" Grid.Column="1" Grid.Row="6" ItemsSource="{Binding SelectedItem, ElementName=ComboCarCompanies}" Text="{Binding Prop[CarType].Value}" DisplayMemberPath="@Type" SelectedValue="{Binding Prop[CarType].Value}" SelectedValuePath="@Type"/>
この例では、ほとんどの属性は、最初のコンボ ボックスと同じ役割を果たします。本質的な相違点は、ItemSource です。この例では、ComboCarCompanies という名前の最初のコンボ ボックスは SelectedItem を参照しています。