HandyControl icon indicating copy to clipboard operation
HandyControl copied to clipboard

[Bug] CheckComboBox unselects all items when all items are selected in constructor

Open mystasly48 opened this issue 2 years ago • 1 comments

Describe the bug When I initialize ItemsSource which all items are selected, CheckComboBox unselects all the selected items. As I traced SelectionChanged event, all selected items are added initially, but immediately all the added items are removed.

To Reproduce I posted a project to reproduce this issue. https://github.com/mystasly48/HandyControlCheckComboBox_BugReproduce

  1. I define CheckComboBox1 as below. Also, I configure IsSelected property to get what item is selected or not.
<hc:CheckComboBox Name="CheckComboBox1" DisplayMemberPath="Name">
  <hc:CheckComboBox.ItemContainerStyle>
    <Style TargetType="hc:CheckComboBoxItem" BasedOn="{StaticResource CheckComboBoxItemBaseStyle}">
      <Setter Property="IsSelected" Value="{Binding IsSelected}" />
    </Style>
  </hc:CheckComboBox.ItemContainerStyle>
</hc:CheckComboBox>
  1. In code behavior, I initialize ItemsSource as below.
public MainWindow() {
  InitializeComponent();
  CheckComboBox1.ItemsSource = new List<Item> {
    new Item("Item 1", true),
    new Item("Item 2", true)
  };
}
  1. Also, Item class is defined as below.
public class Item {
  public string Name { get; set; }
  public bool IsSelected { get; set; }

  public Item(string name, bool selected) {
    this.Name = name;
    this.IsSelected = selected;
  }

  public override string ToString() => Name;
}
  1. After running the program, all the selected items are unselected.

Expected behavior All the selected items should be selected as before.

Environment:

  • .NET 5.0
  • Visual Studio Community 2019, Version 16.10.0
  • HandyControl 3.2.0

mystasly48 avatar Oct 16 '21 17:10 mystasly48

Note: I temporary avoid this issue by adding an unselectable dummy item to ItemsSource. If someone is stuck with the issue, this may helps.

I fixed the Item class as below. I changed IsSelected property to reject to set to true if the item is dummy. Also, Visibility property returns Collapsed if the item is dummy.

public class Item {
  private const string DUMMY_NAME = "DummyItemName";
  public static Item DummyItem => new Item(DUMMY_NAME, false);
  public string Name { get; set; }
  private bool _isSelected;
  public bool IsSelected {
    get => _isSelected;
    set {
      if (value && Name == DUMMY_NAME) return;
      _isSelected = value;
      return _isSelected;
    }
  }
  public Visibility Visibility {
    get {
      if (Name == DUMMY_NAME ) {
        return Visibility.Collapsed;
      } else {
        return Visibility.Visible;
      }
    }
  }

  public Item(string name, bool selected) {
    this.Name = name;
    this.IsSelected = selected;
  }

  public override string ToString() => Name;
}

Then, I use the dummy item to ItemsSource.

public MainWindow() {
  InitializeComponent();
  CheckComboBox1.ItemsSource = new List<Item> {
    Item.DummyItem,
    new Item("Item 1", true),
    new Item("Item 2", true)
  };
}

And in xaml, apply the Visibility property.

<hc:CheckComboBox Name="CheckComboBox1" DisplayMemberPath="Name">
  <hc:CheckComboBox.ItemContainerStyle>
    <Style TargetType="hc:CheckComboBoxItem" BasedOn="{StaticResource CheckComboBoxItemBaseStyle}">
      <Setter Property="IsSelected" Value="{Binding IsSelected}" />
      <Setter Property="Visibility" Value="{Binding Visibility}" />
    </Style>
  </hc:CheckComboBox.ItemContainerStyle>
</hc:CheckComboBox>

mystasly48 avatar Oct 16 '21 18:10 mystasly48

closed in 7519c7e

NaBian avatar Sep 03 '22 10:09 NaBian