Andy From Underhill
Andy From Underhill

Reputation: 115

No highlighted items in my Checked ListBox

I have a checked list box, and I'd like to have the checkboxes be multi-select, but the highlight bar on the list items be single select. With the code listed below, the checkboxes are multi-select, but there is no highlight bar in the listbox, nor can I tell from the listbox which item is currently selected. (lbProtocols.SelectedItems is always 0)

What am I missing?

Here is the xaml for the listbox:

<ListBox Name ="lbProtocols" ItemsSource="{Binding AvailableProtocols}">
  <ListBox.ItemTemplate>
    <HierarchicalDataTemplate>
      <CheckBox Content="{Binding ProtocolName}" IsChecked="{Binding IsChecked}" />
    </HierarchicalDataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

And here is the code behind that binds my observable collection to the listbox:

    public ObservableCollection<CheckedListItem> AvailableProtocols;

    AvailableProtocols = new ObservableCollection<CheckedListItem>();
    CheckedListItem item1 = new CheckedListItem(0, "first", false);
item1.IUPropertyChanged += new PropertyChangedEventHandler(item_IUPropertyChanged);
    CheckedListItem item2 = new CheckedListItem(1, "second", true);
item2.IUPropertyChanged += new PropertyChangedEventHandler(item_IUPropertyChanged);
    CheckedListItem item3 = new CheckedListItem(3, "third", false);
item3.IUPropertyChanged += new PropertyChangedEventHandler(item_IUPropertyChanged);
    AvailableProtocols.Add(item1);
    AvailableProtocols.Add(item2);
    AvailableProtocols.Add(item3);

lbProtocols.ItemsSource = AvailableProtocols;

Here is CheckedListItem class:

public class CheckedListItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public event PropertyChangedEventHandler IUPropertyChanged;

    public CheckedListItem(){ }
    public CheckedListItem(int id, string name, bool check)
    {
        ID = id;
        ProtocolName = name;
        IsChecked = check;
    }

    public int ID { get; set; }
    public string ProtocolName { get; set; }

    private bool _IsChecked;

    public void SetCheckedNoNotify(bool check)
    {
        _IsChecked = check;
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
    }

    public bool IsChecked
    {
        get { return _IsChecked; }
        set
        {
            _IsChecked = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
            if (IUPropertyChanged != null)
                IUPropertyChanged(this, new PropertyChangedEventArgs("IsChecked"));
        }
    }
}

Upvotes: 0

Views: 400

Answers (1)

Malcolm O&#39;Hare
Malcolm O&#39;Hare

Reputation: 5009

Your problem is a common one when using Checkboxes in a ListBoxItem. The checkbox is handling the click event so the listbox is never notified that you selected the item. If you click just to the right of the text beside each item you'll see the row become selected.

The best solution I can suggest is that you split your DataTemplate like this

<DataTemplate>
                    <StackPanel Orientation="Horizontal">
                    <CheckBox  IsChecked="{Binding IsChecked}"  />
                    <TextBlock Text="{Binding ProtocolName}" />
                    </StackPanel>
                </DataTemplate>

Now clicking the text selects the item in the listbox. If you want the checkbox click to cause an item to become selected you'd have to bind to the PropertyChanged for the checkbox item in codebehind and then set

lbProtocols.SelectedItem = sender

Upvotes: 1

Related Questions