Это то, что выглядит довольно безумно, но работает достаточно хорошо.
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ComboBox x:Name="cboTemplate" DisplayMemberPath="Key" SelectedValuePath="Key" SelectedValue="Blue">
<ComboBox.ItemsSource>
<ResourceDictionary>
<DataTemplate x:Key="Blue">
<TextBlock Foreground="Blue" Text="{Binding}" />
</DataTemplate>
<DataTemplate x:Key="Red">
<TextBlock Foreground="Red" Text="{Binding}" />
</DataTemplate>
</ResourceDictionary>
</ComboBox.ItemsSource>
</ComboBox>
<ContentPresenter Grid.Row="1" Content="Hello World" ContentTemplate="{Binding SelectedItem.Value, ElementName=cboTemplate}" />
</Grid>
Словарь ресурсов по сути является коллекцией KeyValuePair<object, object>
, за исключением того, что синтаксический анализ Xaml позволяет использовать его для заполнения с помощью атрибута x:Key
. Таким образом, этот ComboBox отображает свойство Key
, но его SelectedItem
будет KeyValuePair<object, object>
, свойство Value
которого - DataTemplate
, которое мы хотим. Теперь мы можем использовать привязку элемента к элементу в свойстве ContentTemplate
или ItemTemplate
.
Если вам также нужны шаблоны данных, доступные как статические ресурсы, и вы хотите избежать дублирования кода, вы можете поместить их в отдельный файл xaml словаря ресурсов. Затем вы можете использовать: -
<ComboBox.ItemsSource>
<ResourceDictionary Source="DataTemplateResources.xaml" />
</ComboBox.ItemsSource>
А также включить их в статические ресурсы, такие как: -
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DataTemplateResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- other resources here -->
</ResourceDictionary>
</UserControl.Resources>