0

I am trying to bind the ItemsSource and SelectedItem properties of a ComboBox and the items are not displaying properly. The ComboBox is populated with the values of an Enum based on a solution suggested in this post. I have defined the ComboBox on the View as follows:

<ComboBox 
        Grid.Column="1"
        Grid.Row="2"
        ItemContainerStyle="{DynamicResource ComboBoxItemStyle}"
        Style="{DynamicResource MaterialComboBox}"
        SelectedItem="{Binding SelectedSetting}" ItemsSource="{Binding SettingOptions}" />

The properties on ViewModel I bind to are defined as follows:

    private DataUpdateRate _selectedSetting;
    public DataUpdateRate SelectedSetting
    {
        get { return _selectedSetting; }
        set
        {
            _selectedSetting = value;
            OnPropertyChanged("SelectedMyEnumType");
        }
    }

    public IEnumerable<DataUpdateRate> SettingOptions
    {
        get
        {
            return Enum.GetValues(typeof(DataUpdateRate))
                .Cast<DataUpdateRate>();
        }
    }

To the same ComboBox, I have also applied a custom style and template. My guess is that the issue lies in the DataTemplate I defined for the ContentPresenter

<!-- ItemTemplate-->
<Style x:Key="ComboBoxItemStyle" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Padding" Value="6 4"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                <Border 
                    x:Name="itemBorder" 
                    Background="{TemplateBinding Background}" 
                    Padding="{TemplateBinding Padding}" 
                    SnapsToDevicePixels="true">
                    <TextBlock 
                        SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                        HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                        VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                        Text="{TemplateBinding Content}"
                        FontSize="16"
                        FontWeight="Medium"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" TargetName="itemBorder" Value="{StaticResource SurfaceElevation5Brush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- Toggle Button (main button with arrow) -->
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
    <Setter Property="OverridesDefaultStyle" Value="true"/>
    <Setter Property="IsTabStop" Value="false"/>
    <Setter Property="Focusable" Value="false"/>
    <Setter Property="ClickMode" Value="Press"/>
    <Setter Property="Height" Value="40" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ToggleButton}">
                <Border 
                    x:Name="templateRoot" 
                    Background="{StaticResource SurfaceElevation2Brush}" 
                    BorderBrush="{StaticResource SurfaceElevation5Brush}" 
                    BorderThickness="0 0 0 1.5" 
                    CornerRadius="5 5 0 0"
                    SnapsToDevicePixels="true">
                    <Border  
                        SnapsToDevicePixels="true" 
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center"
                        Margin="6 0">
                        <Viewbox Width="15" Height="15">
                            <Path 
                                x:Name="arrow" 
                                Stretch="Fill"
                                Data="M24 30 14 20.05H34Z" 
                                Fill="{StaticResource SurfaceElevation5Brush}"/>
                        </Viewbox>
                        
                    </Border>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource PrimaryLightBrush}" />
                        <Setter Property="Fill" TargetName="arrow" Value="{StaticResource PrimaryLightBrush}"/>
                    </Trigger>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True"/>
                        </MultiDataTrigger.Conditions>
                        <Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource PrimaryBrush}" />
                        <Setter Property="Fill" TargetName="arrow" Value="{StaticResource PrimaryBrush}"/>
                    </MultiDataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>   
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
    <Grid SnapsToDevicePixels="True">

        <!-- Popup -->
        <Popup 
            x:Name="PART_Popup" 
            AllowsTransparency="true" 
            IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" 
            Placement="Bottom" 
            PopupAnimation="Slide">
            <!-- This is the actual dropdown part-->
            <Border 
                x:Name="dropDownBorder"
                SnapsToDevicePixels="True"
                MinWidth="{TemplateBinding FrameworkElement.ActualWidth}"
                MaxHeight="{TemplateBinding ComboBox.MaxDropDownHeight}"
                Background="{StaticResource SurfaceElevation3Brush}" 
                CornerRadius="0 0 5 5">
                <ScrollViewer x:Name="DropDownScrollViewer">
                    <ItemsPresenter 
                        x:Name="ItemsPresenter" 
                        KeyboardNavigation.DirectionalNavigation="Contained" 
                        SnapsToDevicePixels="True"
                        />
                </ScrollViewer>
            </Border>
        </Popup>

        <!-- ToggleButton -->
        <ToggleButton 
            x:Name="toggleButton" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}" 
            BorderThickness="{TemplateBinding BorderThickness}" 
            IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" 
            Style="{StaticResource ComboBoxToggleButton}"/>

        <!-- ContentPresenter -->
        <ContentPresenter 
            x:Name="contentPresenter" 
            ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
            Content="{TemplateBinding SelectionBoxItem}" 
            ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            IsHitTestVisible="false" 
            Margin="10 0" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
            <ContentPresenter.ContentTemplate>
                <DataTemplate>
                    <TextBlock Text="{TemplateBinding Content}" FontSize="16"/>
                </DataTemplate>
            </ContentPresenter.ContentTemplate>
        </ContentPresenter>
    </Grid>
</ControlTemplate>

<!-- Main ComboBo Style -->
<Style x:Key="MaterialComboBox" TargetType="{x:Type ComboBox}">
    <Setter Property="Foreground" Value="{StaticResource ForegroundLightBrush}"/>
    <Setter Property="Padding" Value="6,3,5,3"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Margin" Value="20 0" />
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
    <Setter Property="ScrollViewer.PanningMode" Value="Both"/>
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
</Style>

When I run the application the ComboBox expands according to the number of elements in the Enum, suggesting that it does generate the ComboBoxItems correctly, but doesn't display the values of the items. I have also tried another solution from the post I referenced earlier with the same result.

I assume that I have done something wrong with the ComboBox template, but I can't put my finger on it. If anyone has a solution I would greatly appreciate it.

  • Binding to the Content property of a ContentControl or ContentPresenter is done by `{Binding}` e.g. like ``. – Clemens May 23 '22 at 21:53
  • Also be aware that `OnPropertyChanged("SelectedMyEnumType")` is wrong. Use `OnPropertyChanged(nameof(SelectedSetting))` – Clemens May 23 '22 at 21:54
  • I have replaced the TemplateBinding with a normal Binding and I get a Binding Failure with the Description "Content property not found on object of type DataUpdateRate (which is the name of the Enum)". I assume this is because I haven't set the DataType of the DataTemplate, but I am not sure – Florin Zamfir May 23 '22 at 21:59
  • 1
    I wrote `Text="{Binding}"`, not `Text="{Binding Content}"`. Which is equivalent to `Text="{Binding Path=.}"` – Clemens May 23 '22 at 22:12
  • I am sorry I misunderstood your suggestion. I had no idea that you can do that in XAML. – Florin Zamfir May 23 '22 at 22:26
  • The elements are now displaying nicely, however, when I change the SelectedItem it throws a StackOverflowException. I will have to look into it more. Thank you a lot for your help! – Florin Zamfir May 23 '22 at 22:29

0 Answers0