-
I'm working on a project where I've attempted to create a custom reusable multiselect component ( Setup
<MultiSelectProductCategories @bind-Value="selectedCategories" />
<p>Selected Categories:</p>
<ul>
@foreach (var category in selectedCategories ?? [])
{
<li>@category.Name</li>
}
</ul>
<Button OnClick="@AddElectronics" Color="Color.Success">Add Electronics</Button>
<Button OnClick="@RemoveElectronics" Color="Color.Danger">Remove Electronics</Button>
@code {
private List<ProductCategory>? selectedCategories = null;
private void AddElectronics()
{
var electronics = new ProductCategory { Id = 1, Name = "Electronics" };
selectedCategories ??= new List<ProductCategory>();
if (!selectedCategories.Contains(electronics))
{
selectedCategories.Add(electronics);
StateHasChanged();
}
}
private void RemoveElectronics()
{
if (selectedCategories != null)
{
var electronics = selectedCategories.FirstOrDefault(cat => cat.Name == "Electronics");
if (electronics != null)
{
selectedCategories.Remove(electronics);
if (!selectedCategories.Any())
{
selectedCategories = null;
}
StateHasChanged();
}
}
}
}
<MultiSelectGeneric DisplayText="Types"
ShowLabel="true"
Items="_items"
@bind-Value="_value"
ShowSearch="true"
IsClearable="true"
ShowToolbar="true"
OnSearchTextChanged="HandleOnSearchTextChanged"
OnSelectedItemsChanged="HandleOnSelectedItemsChanged" />
@code {
private List<ProductCategory>? _value = null;
private IEnumerable<SelectedItem<ProductCategory>> _items = Enumerable.Empty<SelectedItem<ProductCategory>>();
[Parameter] public Func<IEnumerable<SelectedItem<ProductCategory>>?, Task>? OnSelectedItemsChanged { get; set; }
[Parameter] public EventCallback<List<ProductCategory>?> ValueChanged { get; set; }
[Parameter]
public List<ProductCategory>? Value
{
get => _value;
set
{
if (!EqualityComparer<List<ProductCategory>?>.Default.Equals(_value, value))
{
_value = value;
if (ValueChanged.HasDelegate)
ValueChanged.InvokeAsync(value);
else
StateHasChanged();
}
}
}
protected override async Task OnInitializedAsync()
{
await LoadProductCategoriesAsync();
}
private async Task LoadProductCategoriesAsync()
{
_items = Enumerable.Empty<SelectedItem<ProductCategory>>();
await Task.Delay(100);
_items = new List<SelectedItem<ProductCategory>>
{
new SelectedItem<ProductCategory> { Text = "Electronics", Value = new ProductCategory { Id = 1, Name = "Electronics" } },
new SelectedItem<ProductCategory> { Text = "Books", Value = new ProductCategory { Id = 2, Name = "Books" } },
new SelectedItem<ProductCategory> { Text = "Home", Value = new ProductCategory { Id = 3, Name = "Home" } }
};
}
private IEnumerable<SelectedItem<ProductCategory>> HandleOnSearchTextChanged(string searchText)
{
return _items.Where(i => (i.Value.Name.Contains(searchText, StringComparison.OrdinalIgnoreCase)));
}
private async Task HandleOnSelectedItemsChanged(IEnumerable<SelectedItem<ProductCategory>>? selectedItems)
{
Value = selectedItems?.Select(x => x.Value).ToList() ?? new List<ProductCategory>();
if (OnSelectedItemsChanged != null)
{
await OnSelectedItemsChanged.Invoke(selectedItems);
}
}
public class ProductCategory
{
public int Id { get; set; }
public string Name { get; set; } = "";
}
} The Problem
What I've Tried
Request for HelpI would appreciate any insights on what might be missing from my implementation to allow external modifications to reflect properly in the UI. Thank you in advance for your help! This issue is a follow-up to dotnetcore/BootstrapBlazor#6363 , where I'm encountering difficulties implementing a custom multiselect component with external item addition reflecting properly in the UI. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
@rabauss Hi. thanks you for submit a discussion. could you upload a zip or create a repo for repro this issue? Creating a new repro project and copying the code here is a lot of work for me |
Beta Was this translation helpful? Give feedback.
-
@ArgoZhang thanks for your great support! I've added a demo of |
Beta Was this translation helpful? Give feedback.
@rabauss
Step1
upgrade
BootstrapBlazor
9.8.3-beta01Step2
add
KeyAttribute
onId
propertyhad submit a PR for this.
Alternatives
add
ValueEqualityComparer
parameter