Hello, I have a component called StorePicker that uses a RadzenDropDown control with multiselect enabled. I'm using this control on a page, and am trying to get two-way binding from a property on the page to work to the Value property on the RadzenDropDown control using a chained bind.
Here is the StorePicker control:
<RadzenDropDown @bind-Value="SelectedStores" Data="@stores" TextProperty="StoreName"
Multiple=true />
@code {
[Parameter]
public IEnumerable<Store> SelectedStores { get; set; } = Enumerable.Empty<Store>();
[Parameter]
public EventCallback<IEnumerable<Store>> SelectedStoresChanged { get; set; }
IEnumerable<Store> stores = Enumerable.Empty<Store>();
protected override async Task OnParametersSetAsync()
{
stores = await GetAllStoresQuery.RunAsync();
await base.OnParametersSetAsync();
}
public class Store
{
public int StoreId { get; set; }
public string StoreName { get; set; }
}
}
And here is a page using the StorePicker control with binding:
@page "/stores"
<StorePicker @ref="storePicker" @bind-SelectedStores="DatabaseSelectedStores" />
<RadzenButton Click="ButtonClicked" Text="Click me" />
@code {
StorePicker storePicker = new StorePicker();
private IEnumerable<Store> DatabaseSelectedStores
{
get => _databaseSelectedStores;
set => _databaseSelectedStores = value;
}
private IEnumerable<Store> _databaseSelectedStores = Enumerable.Empty<Store>();
private void ButtonClicked()
{
var a = _databaseSelectedStores;
var b = storePicker.SelectedStores;
}
}
Using breakpoints I can see that the DatabaseSelectedStores
get
method is called when the page loads; the set
method though is never called, even after selecting some stores. That makes sense, as it should just be adding items to the list, not creating an entirely new list.
However, when I put a breakpoint in the ButtonClicked()
function and click the button, I see that _databaseSelectedStores
has zero items, while storePicker.SelectedStores
has the items I selected in the UI. I would have expected these two variables to refer to the same list behind the scenes, but it seems they do not.
I also experimented a bit with the Change
event on the RadzenDropDown and updating the list property, like this:
<RadzenDropDown @bind-Value="SelectedStores" Data="@stores" TextProperty="StoreName"
Multiple=true Change="@(args => SelectedStoresUpdated())" />
@code {
...
private void SelectedStoresUpdated()
{
SelectedStoresChanged.InvokeAsync(SelectedStores);
}
}
This seemed to work better. I now saw the DatabaseSelectedStores
set
method being called each time I selected an item in the dropdown menu, and when I click the button the _databaseSelectedStores
and storePicker.SelectedStores
variables contain the same items that I selected in the UI. However, using this method, while selected items do get added to the dropdown control's list of selected items, the checkboxes do not stay checked when you select them, and it allows you to add multiple of the same item instead of toggling the item from being selected (see screenshot below).
I thought perhaps that different store instances were being seen differently, even though they had the same value, so I implemented IEqualityComparer
on the Store
class like below, but it did not seem to make a difference.
public class Store : IEqualityComparer<Store>
{
public int StoreId { get; set; }
public string StoreName { get; set; }
public bool Equals(Store x, Store y)
{
return x.StoreId == y.StoreId && x.StoreName == y.StoreName;
}
public int GetHashCode([DisallowNull] Store obj)
{
return HashCode.Combine(obj.StoreId, obj.StoreName);
}
}
So I'm not sure if I'm doing something wrong, or if there is perhaps a bug in the RadzenDropDown control and how it shows which items are selected. Any help or suggestions are appreciated. Thanks!