WPF:ComboBox:在 Style / ControlTemplate 中公开 DataTemplate 绑定

WPF: ComboBox: exposing DataTemplate bindings in Style / ControlTemplate

假设我有一个这样定义的示例 ComboBox

<ComboBox   ItemsSource="{Binding Path=Bikes}"
            HorizontalAlignment="Stretch">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Ellipse Fill="{DynamicResource AccentColorBrush}"
                            Height="15"
                            Width="15" 
                            VerticalAlignment="Center"/>
                <TextBlock  Text="{Binding Type}"
                            Margin="15, 0, 0, 0"
                            FontWeight="SemiBold"
                            Foreground="{DynamicResource AccentColorBrush}"
                            VerticalAlignment="Center"/>
            </StackPanel>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

我想做的是将它包裹在 Style 中,但暴露 ComboBoxText [=] 的 ItemSource 属性 22=] 在 DataTemplate 中,这样我每次使用 ComboBox 时都可以绑定到不同的属性。

我可以建议您使用 ViewModel-First 方法创建一个组合框样式,该样式将 select 其组合项的模板。因此会有许多数据模板,每个模板都与特定的视图模型相关。

<Window x:Class="WpfViewConstructorCall.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfViewConstructorCall"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="525"
    Height="350"
    mc:Ignorable="d">
<Window.Resources>
    <!--Combo-item data-template wich is defining the final item view-->
    <DataTemplate x:Key="ComboItemContentTemplate">
        <StackPanel Orientation="Horizontal">
            <Ellipse Width="15"
                     Height="15"
                     VerticalAlignment="Center"
                     Fill="GreenYellow" />
            <TextBlock Margin="15, 0, 0, 0"
                       VerticalAlignment="Center"
                       FontWeight="SemiBold"
                       Foreground="Red"
                       Text="{Binding}" />
        </StackPanel>
    </DataTemplate>
    <!--Combo-item data-template wich relates to ItemA view-model-->
    <DataTemplate DataType="{x:Type local:ItemA}">
        <ContentControl Content="{Binding Name}"
                        ContentTemplate="{StaticResource ComboItemContentTemplate}" />
    </DataTemplate>
    <!--Combo-item data-template wich relates to ItemB view-model-->
    <DataTemplate DataType="{x:Type local:ItemB}">
        <ContentControl Content="{Binding Kind}"
                        ContentTemplate="{StaticResource ComboItemContentTemplate}" />
    </DataTemplate>
    <!--Combo-item data-template wich relates to ItemC view-model-->
    <DataTemplate DataType="{x:Type local:ItemC}">
        <ContentControl Content="{Binding Type}"
                        ContentTemplate="{StaticResource ComboItemContentTemplate}" />
    </DataTemplate>
    <!--main Combo-item data-template-->
    <DataTemplate x:Key="ComboItemDataTemplate">
        <ContentControl Content="{Binding}" />
    </DataTemplate>
    <!--Combo style-->
    <Style x:Key="ComboBoxStyle"
           TargetType="ComboBox">
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="ItemTemplate" Value="{StaticResource ComboItemDataTemplate}" />
    </Style>
</Window.Resources>
<Grid>
    <Grid.DataContext>
        <local:GridDataContext />
    </Grid.DataContext>
    <StackPanel>
        <!--Combo(s) with specific source definition-->
        <ComboBox x:Name="A"
                  DisplayMemberPath="Name"
                  ItemsSource="{Binding ItemsA}"
                  SelectedValuePath="Name"
                  Style="{StaticResource ComboBoxStyle}" />
        <ComboBox x:Name="B"
                  DisplayMemberPath="Kind"
                  ItemsSource="{Binding ItemsB}"
                  SelectedValuePath="Kind"
                  Style="{StaticResource ComboBoxStyle}" />
        <ComboBox x:Name="C"
                  DisplayMemberPath="Type"
                  ItemsSource="{Binding ItemsC}"
                  SelectedValuePath="Type"
                  Style="{StaticResource ComboBoxStyle}" />
    </StackPanel>
</Grid></Window>

如果您将有一个额外的组合项的视图模型,您将添加一个数据模板,该模板将与该特定视图模型相关并定义其视图。

如果您需要更多示例,请告诉我。

此致。