简体   繁体   中英

WPF: ComboBox: exposing DataTemplate bindings in Style / ControlTemplate

Lets say I have a sample ComboBox defined like this.

<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>

What I would like to do is to wrap it in a Style , but expose the ItemSource property of ComboBox and Text property within DataTemplate , so that I can Bind to different properties each time I use ComboBox .

I can suggest you to create a combo-box style that will select the template of its combo-item using the ViewModel-First approach. So there will be number of data-templates each of wich will relate to specific view-model.

<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>

In case you will have an additional combo-item's view model you will add a data-template which will relate to that specific view-model and will define its view.

Let me knnow if you need more examples.

Best regards.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM