2

Based on this answer I tried to use the following code to achieve a ComboBox with different templates depending on whether or not the drop down is open. The ComboBox definition looks like this:

<ComboBox SelectedValuePath="Id"
          DisplayMemberPath="Name">
    <ComboBox.Resources>
        <DataTemplate x:Key="SelectedTemplate">
            <TextBlock Text="Abbreviation" />
        </DataTemplate>

        <DataTemplate x:Key="DropDownTemplate">
            <ContentControl Content="{Binding}">
                <ContentControl.Style>
                    <Style TargetType="{x:Type ContentControl}">
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <Grid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Border}}, Path=ActualWidth, Mode=OneTime}">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="20" />
                                        </Grid.ColumnDefinitions>

                                        <TextBlock Grid.Column="0"
                                                   Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}, Path=DisplayMemberPath}" />
                                        <TextBlock Grid.Column="1" 
                                                   Text="Abbreviation" />
                                    </Grid>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ContentControl.Style>
            </ContentControl>
        </DataTemplate>

        <infrastructure:ComboBoxItemTemplateSelector x:Key="ComboBoxItemTemplateSelector"
                                                 DropDownDataTemplate="{StaticResource DropDownTemplate}"
                                                 SelectedDataTemplate="{StaticResource SelectedTemplate}" />
    </ComboBox.Resources>
</ComboBox>

and the ComboBoxItemTemplateSelector looks like this:

public class ComboBoxItemTemplateSelector : DataTemplateSelector
{
    public DataTemplate DropDownDataTemplate { get; set; }
    public DataTemplate SelectedDataTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        return DependencyObjectHelper.GetVisualParent<ComboBoxItem>(container) != null ? this.DropDownDataTemplate : this.SelectedDataTemplate;
    }
}

Now the problem is that somehow SelectTemplate is never called, even although I checked all the DynamicResources and StaticResources.

  • 3
    Don't set DisplayMemberPath. And assign an instance of ComboBoxItemTemplateSelector to the ComboBox's ItemTemplateSelector property. – Clemens Mar 14 '18 at 13:29
  • 1
    @Clemens Thank you for the edit on my answer. Just out of curiosity, why did you remove the part mentioning that it's basically only what you have already said? I just wanted to give you the credits for that, it was not meant to be bad or anything. – Thomas Flinkow Mar 14 '18 at 13:40
  • 2
    @Thomas I don't think doing so is necessary. IMO questions and answer should only contain essential content. – Clemens Mar 14 '18 at 13:44

1 Answers1

0

You need to assign the ComboBoxItemTemplateSelector to the ComboBox like this:

<ComboBox ItemTemplateSelector="{DynamicResource ComboBoxItemTemplateSelector}">

and you cannot set the DisplayMemberPath or the SelectTemplate method will never be called.

Clemens
  • 123,504
  • 12
  • 155
  • 268
Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65