RadzenPickList selection by ValueProperty fixed

This commit is contained in:
Vladimir Enchev
2026-01-08 10:08:29 +02:00
parent f1c3f46ad7
commit 4e7a037bc5
3 changed files with 88 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
using Bunit;
using Xunit;
using System.Collections.Generic;
using System.Linq;
namespace Radzen.Blazor.Tests
{
@@ -156,6 +157,64 @@ namespace Radzen.Blazor.Tests
Assert.Contains("disabled", component.Markup);
}
[Fact]
public void PickList_GetSelectedSources_Respects_ValueProperty_Single()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var data = new List<Item>
{
new Item { Id = 1, Name = "A" },
new Item { Id = 2, Name = "B" }
};
var component = ctx.RenderComponent<RadzenPickList<Item>>(parameters =>
{
parameters.Add(p => p.Source, data);
parameters.Add(p => p.TextProperty, "Name");
parameters.Add(p => p.ValueProperty, "Id");
parameters.Add(p => p.Multiple, false);
});
// Simulate ListBox selection when ValueProperty is set: selectedSourceItems becomes the value (Id)
var field = typeof(RadzenPickList<Item>).GetField("selectedSourceItems", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
field.SetValue(component.Instance, 2);
var selected = component.Instance.GetSelectedSources();
Assert.Single(selected);
Assert.Equal(2, selected.First().Id);
}
[Fact]
public void PickList_GetSelectedSources_Respects_ValueProperty_Multiple()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
var data = new List<Item>
{
new Item { Id = 1, Name = "A" },
new Item { Id = 2, Name = "B" },
new Item { Id = 3, Name = "C" }
};
var component = ctx.RenderComponent<RadzenPickList<Item>>(parameters =>
{
parameters.Add(p => p.Source, data);
parameters.Add(p => p.TextProperty, "Name");
parameters.Add(p => p.ValueProperty, "Id");
parameters.Add(p => p.Multiple, true);
});
// Simulate ListBox selection when ValueProperty is set: selectedSourceItems becomes IEnumerable of values (Ids)
var field = typeof(RadzenPickList<Item>).GetField("selectedSourceItems", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
field.SetValue(component.Instance, new[] { 1, 3 });
var selected = component.Instance.GetSelectedSources().Select(i => i.Id).OrderBy(i => i).ToArray();
Assert.Equal(new[] { 1, 3 }, selected);
}
}
}

View File

@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Radzen;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -377,19 +378,38 @@ namespace Radzen.Blazor
/// Returns a collection of TItem that are selected in the source list.
/// </summary>
/// <returns></returns>
public IEnumerable<TItem> GetSelectedSources() =>
Multiple
? (selectedSourceItems as IEnumerable)?.Cast<TItem>() ?? Enumerable.Empty<TItem>()
: selectedSourceItems is TItem item ? new[] { item } : Enumerable.Empty<TItem>();
public IEnumerable<TItem> GetSelectedSources() => GetSelectedItems(selectedSourceItems, source);
/// <summary>
/// Returns a collection of TItem that are selected in the target list.
/// </summary>
/// <returns></returns>
public IEnumerable<TItem> GetSelectedTargets() =>
Multiple
? (selectedTargetItems as IEnumerable)?.Cast<TItem>() ?? Enumerable.Empty<TItem>()
: selectedTargetItems is TItem item ? new[] { item } : Enumerable.Empty<TItem>();
public IEnumerable<TItem> GetSelectedTargets() => GetSelectedItems(selectedTargetItems, target);
IEnumerable<TItem> GetSelectedItems(object? selectedItems, IEnumerable<TItem>? data)
{
if (selectedItems == null)
{
return Enumerable.Empty<TItem>();
}
var selected = Multiple
? (selectedItems as IEnumerable)?.Cast<object?>().ToList() ?? new List<object?>()
: new List<object?> { selectedItems };
if (selected.Count > 0 && selected.All(o => o is TItem))
{
return selected.Cast<TItem>();
}
if (!string.IsNullOrEmpty(ValueProperty) && data != null)
{
var selectedValues = new HashSet<object?>(selected);
return data.Where(item => selectedValues.Contains(PropertyAccess.GetValue(item, ValueProperty)));
}
return Enumerable.Empty<TItem>();
}
RadzenListBox<object>? sourceListBox;
RadzenListBox<object>? targetListBox;

View File

@@ -83,7 +83,7 @@
</RadzenCard>
<RadzenCard>
<RadzenPickList AllowMoveAll="@allowMoveAll" AllowMoveAllSourceToTarget="@allowMoveSourceToTarget" AllowMoveAllTargetToSource="@allowMoveTargetToSource" @bind-Source="@Source" @bind-Target="@Target" Style="height:500px; width:100%;" Orientation="@orientation"
TextProperty="@nameof(Customer.CompanyName)" AllowFiltering="@allowFilter" MoveFilteredItemsOnlyOnMoveAll="@moveFilteredItemsOnlyOnMoveAll" Multiple="@multiple" ShowHeader="@showHeader" Disabled="@disabled"
TextProperty="@nameof(Customer.CompanyName)" ValueProperty="@nameof(Customer.CustomerID)" AllowFiltering="@allowFilter" MoveFilteredItemsOnlyOnMoveAll="@moveFilteredItemsOnlyOnMoveAll" Multiple="@multiple" ShowHeader="@showHeader" Disabled="@disabled"
ButtonGap="@gap" ButtonJustifyContent="@justifyContent" ButtonStyle="@style" ButtonSize="@size" ButtonShade="@shade" ButtonVariant="@variant"
AllowSelectAll="@allowSelectAll"
ItemRender="OnItemRender">