Search code examples
c#wpfxamlcheckboxlistbox

WPF Listbox multiple selection with CheckBox in template


I have a listbox with a datatemplate that contains a checkbox and textblock. How do I get the multiselection working with the checkbox in the template so that selection is based on the isChecked property of the checkbox? The need I have is to have a dropdown with checkboxes that could cater for multiselection. This is what I have sofar. Please feel free to give suggestions on where I could better this code as this is the whole point.

enter image description here

XAML:

     <DataTemplate x:Key="WorkCentreItem">
            <StackPanel Orientation="Horizontal">
                <CheckBox Content="{Binding WorkCentre}" IsChecked="{Binding IsChecked}"/>
                <TextBlock Text=" -  "/>
                <TextBlock Text="{Binding Description}"/>
            </StackPanel>
        </DataTemplate>

     <telerik:RadListBox 
        SelectionMode="Multiple" 
        Grid.Row="2" 
        Grid.ColumnSpan="2" 
        Grid.RowSpan="1" 
        Margin="-1,20,0,3"
        ItemsSource="{Binding SampleWorkCentres}"
        ItemTemplate="{StaticResource WorkCentreItem}" 
        ScrollViewer.CanContentScroll="True"
        SelectionChanged="RadListBox_SelectionChanged">         
    </telerik:RadListBox>

Model:

    #region SampleWorkCentres
    public const string SampleWorkCentresPropertyName = "SampleWorkCentres";
    private ObservableCollection<BomWorkCentre> _sampleWorkCentres;
    public ObservableCollection<BomWorkCentre> SampleWorkCentres
    {
        get
        {
            if (this._sampleWorkCentres == null)
            {
                using (SysproKitIssueEntities db = new SysproKitIssueEntities())
                {
                    this._sampleWorkCentres = new ObservableCollection<BomWorkCentre>(db.BomWorkCentres.Select(x => x).Distinct().ToList());
                }
            }
            return this._sampleWorkCentres;
        }

        set
        {
            if (this._sampleWorkCentres == value)
            {
                return;
            }
            this._sampleWorkCentres = value;
            this.RaisePropertyChanged(SampleWorkCentresPropertyName);
        }
    }
    #endregion

    #region SelectedWorkCentres
    public const string SelectedWorkCentresPropertyName = "SelectedWorkCentres";
    private ObservableCollection<BomWorkCentre> _selectedWorkCentres = new ObservableCollection<BomWorkCentre>();
    public ObservableCollection<BomWorkCentre> SelectedWorkCentres
    {
        get
        {
            return this._selectedWorkCentres;
        }

        set
        {
            if (this._selectedWorkCentres != value)
            {
                this._selectedWorkCentres = value;
            }
            this._sampleGridItems = null;
            this.RaisePropertyChanged(SampleGridItemsPropertyName);
            this.RaisePropertyChanged(SelectedWorkCentresPropertyName);
        }
    }
    #endregion

Solution

  • You should data bind the Checkbox.IsChecked to the ListBoxItem.IsSelected Property using a RelativeSource Binding:

    <CheckBox Content="{Binding WorkCentre}" IsChecked="{Binding IsSelected, 
        RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}" />