Hi,

I need to have a ComboBox that displays a list of CheckBoxes when dropped down so the user can check the relevant ones and then close it again. When closed, I want the ComboBox (the 'Text' area) to display the number of checked items (for example "Checked items: 3").

I cannot seem to figure this out... I can get the CheckBoxes in the ComboBox, that's easy enough using a DataTemplate, but then it also uses the same template for the 'selected item' and thus shows the last clicked ("selected") CheckBox in the text area. Selecting an item is actually not really defined for this ComboBox, I just need the user to check some items and be done with it, he doesn't need to select any items.

I've tried looking for solutions, and there seem to be a few different solutions to having a different template for the selected item as for the dropdown items, but none seem to work for me...

The code-behind for all of my attempts is:
vb.net Code:
  1. Imports System.Collections.ObjectModel
  2.  
  3. Class MainWindow
  4.  
  5.     Private items As ObservableCollection(Of ComboBoxItem)
  6.  
  7.     Public Sub New()
  8.  
  9.         ' This call is required by the designer.
  10.         InitializeComponent()
  11.  
  12.         ' Add any initialization after the InitializeComponent() call.
  13.  
  14.         items = New ObservableCollection(Of ComboBoxItem)
  15.         For i As Integer = 1 To 5
  16.             items.Add(New ComboBoxItem() With {.Text = "Item " & i})
  17.         Next
  18.  
  19.         comboBox.ItemsSource = items
  20.  
  21.     End Sub
  22.  
  23.     Private ReadOnly Property CheckedItems As Integer
  24.         Get
  25.             Return items.Where(Function(cbi) cbi.IsChecked).Count()
  26.         End Get
  27.     End Property
  28.  
  29. End Class
  30.  
  31. Public Class ComboBoxItem
  32.  
  33.     Private _Text As String
  34.     Public Property Text() As String
  35.         Get
  36.             Return _Text
  37.         End Get
  38.         Set(ByVal value As String)
  39.             _Text = value
  40.         End Set
  41.     End Property
  42.  
  43.     Private _IsChecked As Boolean
  44.     Public Property IsChecked() As Boolean
  45.         Get
  46.             Return _IsChecked
  47.         End Get
  48.         Set(ByVal value As Boolean)
  49.             _IsChecked = value
  50.         End Set
  51.     End Property
  52.  
  53. End Class

Attempt 1:
Source
My XAML code:
Code:
    <Window.Resources>   
        <ControlTemplate x:Key="X" TargetType="{x:Type ContentControl}">
            <CheckBox Content="{Binding Text}" IsChecked="{Binding IsChecked}" />
        </ControlTemplate>
    </Window.Resources>
    
    <Grid>
        <ComboBox Name="comboBox" VerticalAlignment="Top" Margin="10">                  
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=CheckedItems}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
            <ComboBox.ItemContainerStyle>
                <Style TargetType="{x:Type ComboBoxItem}">
                    <Setter Property="Margin" Value="5"/>
                    <Setter Property="Template" Value="{StaticResource X}" />
                </Style>
            </ComboBox.ItemContainerStyle>
        </ComboBox>
    </Grid>
I am trying to bind the TextBlock Text property to the 'CheckedItems' property in my Window, I hope I'm not screwing that up...

Anyway, the result is a dropdown containing CheckBox items which I can check (correct), but after closing, the 'text area' remains empty. Even if I select an item (which isn't really defined for me) it displays nothing.



(Text too long, see post 2...)