0
votes

My listbox is binded to an items source and selecteditem property is also binded. Most of my work is being done in selecteditem property. Actually I have two listboxes, for each item in first list box there are some child items in the collection. Against all the items that are selected in first listbox, their child items are supposed to be added in the second list box.

Problem is Selecting the item(by checking the checkbox) does not raise the SelectedItem property changed

XAML for my listbox controls are

 <ListBox SelectionMode="Multiple" ItemsSource="{Binding Charts,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedChart, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
          <ListBox.ItemTemplate>
                <DataTemplate>
                     <CheckBox Content="{Binding ChartName}" VerticalAlignment="Center" IsChecked="{Binding IsChartSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                 </DataTemplate>
            </ListBox.ItemTemplate>
</ListBox>

<ListBox ItemsSource="{Binding Tracks, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
            <ListBox.ItemTemplate>
                <DataTemplate >
                    <StackPanel Orientation="Horizontal">
                        <CheckBox  VerticalAlignment="Center" IsChecked="{Binding IsTrackSelected}"/>
                        <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding TrackName}"/>
                    </StackPanel>
                </DataTemplate>
   </ListBox.ItemTemplate>

My Chart Selection Changed property in view model is

  public ChartSourceForMultipleSelection SelectedChart
    {
        get { return _selectedChart; }
        set
        {
            _selectedChart = value;
            ChartSelectionChanged();
            NotifyPropertyChanged("SelectedChart");
        }
    }
1

1 Answers

1
votes

This binding doesn't make any sense:

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

This attempts to bind to a property IsTrackSelected on the outer ListBoxItem, but no such property exists. It doesn't look like you need a RelativeSource here, provided IsTrackSelected is a property of the underlying data item.

Also, I'm not sure why you're a ListBox for the tracks collection; it looks like your concepts of track selection is separate from the ListBox concept of a selected item. Why not use a simple ItemsControl instead?

As to your primary problem, the CheckBox in the item template is eating the mouse/focus events that would normally tell the ListBox to select the parent ListBoxItem when clicked. You can manually update the selection state of a ListBoxItem whenever its inner CheckBox receives keyboard focus.

Add GotKeyboardFocus="OnChartCheckBoxGotKeyboardFocus" to the CheckBox your chart list item template, give the chart list box a name, e.g., x:Name="ChartsList", and write the handler in the code behind:

private void OnChartCheckBoxGotKeyboardFocus(
    object sender,
    KeyboardFocusChangedEventArgs e)
{
    var checkBox = sender as CheckBox;
    if (checkBox == null)
        return;

    var listBoxItem = ItemsControl.ContainerFromElement(ChartsList, checkBox)
                      as ListBoxItem;
    if (listBoxItem != null)
        listBoxItem.IsSelected = true;
}