DropDown Multiple not working? -- resolved

Hey,

i'm working with free Blazor components, i'm using RadzenDropDown with list of arbitrary objects, component is able to bind selected object to my model, just lovely. But then i tried Multiple atribute and
i don't know what i'm doing wrong, but i'm unable to get it work. It behaves really strange. First, my setup:

  • .NET 6
  • Blazor WebAssembly
  • Radzen.Blazor v4.2.2 (it didn't worked in previous version either...)

First, i expected, that multiselect will be able to bind multiple arbitrary objects from data source to the model, which didn't work, because when i clicked dropdown item (or checkbox directly) checkbox will not get checkmark but the element is added to the model. Problem is, that i can click that same item multiple times, checkbox is never checked and each click will add that item to the model list. I thought it strange but because Blazor Dropdown component with multiple selection support is using only simple model values like IEnumerable<int> or IEnumerable<string> i thought that the values comparer, which checks if model already contains that item and either adds it or removes it can't work with arbitrary objects. Ok, so i simplified my model to just list of ints. But it doesn't work either, now every time i click a item, checkmark is not added and that same item is selected twice for the first click and then the number of model items are just multiplying. Anyway, i must be doing something really wrong, here is my code:

<RadzenDropDown
	@bind-Value="multi"
	Data="@items"
	TValue="IEnumerable<int>"
	ValueProperty="@nameof(SelectTest.Id)"
	TextProperty="@nameof(SelectTest.Text)"
	AllowClear
	Multiple
/>

@code {
	public class SelectTest
	{
		public int Id		{ get; set; }
		public string? Text	{ get; set; }
		public bool More	{ get; set; }
	}

	private readonly IEnumerable<SelectTest> items = Enumerable
		.Range(1, 20)
		.Select(x => new SelectTest {
			Id = x,
			Text = $"Test #{x}",
			More = x % 2 == 0
		});

	private IEnumerable<int>? multi;
}

State of UI after i opened dropdown and clicked on "Test #1" (also note, that i got chips even if i didn't specify them in attributes and they sould be off by default):
dropdown

So i spoke too soon, i don't really understand why, but when i change IEnumerable to List it works fine even with arbitrary objects.

Changes for clarity:

<RadzenDropDown
	@bind-Value="multi"
	Data="@items"
	TValue="List<SelectTest>"
	TextProperty="@nameof(SelectTest.Text)"
	AllowClear
	Multiple
/>

@code {
	public class SelectTest
	{
		public int Id		{ get; set; }
		public string? Text	{ get; set; }
		public bool More	{ get; set; }
	}

	private readonly List<SelectTest> items = Enumerable
		.Range(1, 20)
		.Select(x => new SelectTest {
			Id = x,
			Text = $"Test #{x}",
			More = x % 2 == 0
		})
		.ToList();

	private List<SelectTest> multi = new List<SelectTest>();
}

When you use IEnumerable every time the component touches Data property internally you actually return new set of items with different hash codes and checking if some item is selected or not will not work as expected.

Thank you, it makes sense, IEnumerable is always evaluated when is accessed. I'm curious though why are IEnumerables working in your example on the blazor.radzen.com...

Our demos use ToList() when initializing the collections which fixes this issue. For what is worth you can make it work as it is (without calling ToList()) by overriding the Equals method of the SelectTest class

	public class SelectTest
	{
		public int Id		{ get; set; }
		public string? Text	{ get; set; }
		public bool More	{ get; set; }

        public override bool Equals(object o)
        {
            var other = o as SelectTest;

            return other?.Id == Id;
        }
}

Then the checks we do will pass even when the instances change. Still there is room for improvement and we will investigate further.

Thank you, that Equals override is actually really clever, because then it allows to "edit" select (even multiple) with model populated with items, which should be pre-selected.

Would be really nice to mention it somewhere in the dropdown docs.

In the next update (Monday) this case will work properly without overriding Equals():

2 Likes