Home > Blockchain >  Bind WPF Combobox Item Background
Bind WPF Combobox Item Background

Time:12-06

I'm trying to have a list from a combobox that highlights certain values, and the criteria for highlighting is a boolean. I have been able to make it work in testing by manually adding each combobox item manually and marking the tag, but I need it to be bound to be more dynamic. I've tried a couple different ways, but the dictionary seems like the simplest.

Dictionary

XAML:

<ComboBox Name="Box" HorizontalAlignment="Left" Margin="81,102,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Items.Keys}">
            <ComboBox.Resources>
                <Style TargetType="{x:Type ComboBoxItem}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Items.Values}" Value="True">
                            <Setter Property="Background" Value="Yellow"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ComboBox.Resources>
        </ComboBox>

Code-behind:

Public Module GlobalVariables
    Public Item As New TestItem
End Module
Class MainWindow
    Public Sub New()
        InitializeComponent()
        DataContext = Item
    End Sub
End Class

Public Class TestItem
    Public Property Items As New Dictionary(Of String, Boolean)
    Public Sub New()
        Items.Add("1", False)
        Items.Add("2", True)
        Items.Add("3", False)
        Items.Add("4", False)
        Items.Add("5", True)
    End Sub
End Class

I'm guessing that my issue is that I'm using the collection of the dictionary values as the datatrigger binding rather than the individual one, but I'm not sure how to get the value associated with the key in XAML.

Thanks for any help

EDIT

Thanks to Tarazed's answer, I was able to get the test to work with this:

XAML:

<ComboBox Name="Box" HorizontalAlignment="Left" Margin="81,102,0,0" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedObject}" DisplayMemberPath="Name">
        <ComboBox.Resources>
            <Style TargetType="{x:Type ComboBoxItem}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Highlighted}" Value="True">
                        <Setter Property="Background" Value="Yellow"/>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ComboBox.Resources>
    </ComboBox>

Code-behind:

Public Module GlobalVariables
    Public TestCollection As New ItemCollection
End Module
Class MainWindow
    Public Sub New()
        InitializeComponent()
        DataContext = TestCollection
    End Sub
End Class

Public Class Item
    Public Property Highlighted As Boolean
    Public Property Name As String
End Class

Public Class ItemCollection
    Public Property Items As New List(Of Item)
    Public Property SelectedObject As Item
    Public Sub New()
        Items.Add(New Item With {.Name = "1", .Highlighted = False})
        Items.Add(New Item With {.Name = "2", .Highlighted = True})
        Items.Add(New Item With {.Name = "3", .Highlighted = False})
        Items.Add(New Item With {.Name = "4", .Highlighted = False})
        Items.Add(New Item With {.Name = "5", .Highlighted = True})
    End Sub
End Class

CodePudding user response:

You are correct, the binding is unable to associate the boolean value with the string because calling on .Keys and .Values produces two collectins.

Instead, take a look at the DisplayMemberPath of the ItemsControl (ComboBox). This allows you to pick the property of a complex object to be displayed by the control. Using this you can create a collection, rather than a dictionary, of instances of a custom structure or class containing the name and highlight boolean and choose the name for display.

  • Related