Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/BootstrapBlazor.Server/Components/Samples/MultiSelects.razor
Original file line number Diff line number Diff line change
Expand Up @@ -325,26 +325,28 @@ private enum MultiSelectEnumFoo
<p class="code-label">1. 使用 OnQueryAsync 作为数据源</p>
<div class="row mb-3">
<div class="col-6">
<MultiSelect IsVirtualize="true" @bind-Value="_virtualItemString1" OnQueryAsync="OnQueryAsync"
<MultiSelect IsVirtualize="true" @bind-Value="_virtualItemValue1" DefaultVirtualizeItemText="@_virtualItemText1"
OnQueryAsync="OnQueryAsync"
ShowSearch="_showSearch" ShowToolbar="_showToolbar"
IsClearable="_isClearable">
</MultiSelect>
</div>
<div class="col-6">
<Display TValue="string" Value="@_virtualItemString1"></Display>
<Display TValue="string" Value="@_virtualItemValue1"></Display>
</div>
</div>

<p class="code-label">2. 使用 Items 作为数据源</p>
<div class="row">
<div class="col-6">
<MultiSelect IsVirtualize="true" @bind-Value="_virtualItemString2" Items="VirtualItems"
<MultiSelect IsVirtualize="true" @bind-Value="_virtualItemValue2" DefaultVirtualizeItemText="@_virtualItemText2"
Items="VirtualItems"
ShowSearch="_showSearch" ShowToolbar="_showToolbar"
IsClearable="_isClearable">
</MultiSelect>
</div>
<div class="col-6">
<Display TValue="string" Value="@_virtualItemString2"></Display>
<Display TValue="string" Value="@_virtualItemValue2"></Display>
</div>
</div>
</DemoBlock>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ private enum MultiSelectEnumFoo
[NotNull]
private List<Foo>? Foos { get; set; }

private string? _virtualItemString1;
private string? _virtualItemValue1;
private string? _virtualItemValue2;
private string? _virtualItemText1;
private string? _virtualItemText2;

private string? _virtualItemString2;

private IEnumerable<SelectedItem> VirtualItems => Foos.Select(i => new SelectedItem(i.Name!, i.Name!)).ToList();
private IEnumerable<SelectedItem> VirtualItems => Foos.Select(i => new SelectedItem(i.Id.ToString(), i.Name!)).ToList();

private string? _editString;
private bool _isClearable = true;
Expand Down Expand Up @@ -213,8 +214,10 @@ protected override void OnInitialized()

Items = GenerateDataSource(DataSource);
Foos = Foo.GenerateFoo(LocalizerFoo);
_virtualItemString1 = Foos[79].Name;
_virtualItemString2 = Foos[45].Name;
_virtualItemValue1 = $"{Foos[79].Id}, {Foos[78].Id}";
_virtualItemValue2 = $"{Foos[45].Id}, {Foos[46].Id}";
_virtualItemText1 = $"{Foos[79].Name}, {Foos[78].Name}";
_virtualItemText2 = $"{Foos[45].Name}, {Foos[46].Name}";
}

private static List<SelectedItem> GenerateItems() =>
Expand Down Expand Up @@ -482,6 +485,14 @@ private AttributeItem[] GetAttributes() =>
Type = "bool",
ValueList = "true|false",
DefaultValue = "false"
},
new()
{
Name = nameof(MultiSelect<string>.DefaultVirtualizeItemText),
Description = Localizer["MultiSelectsAttribute_DefaultVirtualizeItemText"],
Type = "string",
ValueList = " — ",
DefaultValue = " — "
}
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,14 @@ private AttributeItem[] GetAttributes() =>
Type = "bool",
ValueList = "true|false",
DefaultValue = "false"
},
new()
{
Name = nameof(Select<string>.DefaultVirtualizeItemText),
Description = Localizer["SelectsDefaultVirtualizeItemText"],
Type = "string",
ValueList = " — ",
DefaultValue = " — "
}
];
}
6 changes: 4 additions & 2 deletions src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -3031,7 +3031,8 @@
"MultiSelectVirtualizeIntro": "Set <code>IsVirtualize</code> to <b>true</b> enable virtual scroll for large data",
"MultiSelectVirtualizeDescription": "Component virtual scrolling supports two ways of providing data through <code>Items</code> or <code>OnQueryAsync</code> callback methods",
"MultiSelectsAttribute_ShowSearch": "Whether to display the search box",
"MultiSelectsAttribute_IsVirtualize": "Wether to enable virtualize"
"MultiSelectsAttribute_IsVirtualize": "Wether to enable virtualize",
"MultiSelectsAttribute_DefaultVirtualizeItemText": "The text string corresponding to the first load value when virtual scrolling is turned on is separated by commas"
},
"BootstrapBlazor.Server.Components.Samples.Radios": {
"RadiosTitle": "Radio",
Expand Down Expand Up @@ -3208,7 +3209,8 @@
"SelectsOnInputChangedCallback": "Callback method for converting input text into corresponding Value in edit mode",
"TextConvertToValueCallback": "Callback method when input text changes in edit mode",
"SelectsIsEditable": "Whether editable",
"SelectsIsVirtualize": "Wether to enable virtualize"
"SelectsIsVirtualize": "Wether to enable virtualize",
"SelectsDefaultVirtualizeItemText": "The text string corresponding to the first load value when virtual scrolling is turned on is separated by commas"
},
"BootstrapBlazor.Server.Components.Samples.Sliders": {
"SlidersTitle": "Slider",
Expand Down
6 changes: 4 additions & 2 deletions src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -3031,7 +3031,8 @@
"MultiSelectVirtualizeIntro": "通过设置 <code>IsVirtualize</code> 参数开启组件虚拟功能特性",
"MultiSelectVirtualizeDescription": "组件虚拟滚动支持两种形式通过 <code>Items</code> 或者 <code>OnQueryAsync</code> 回调方法提供数据",
"MultiSelectsAttribute_ShowSearch": "是否显示搜索框",
"MultiSelectsAttribute_IsVirtualize": "是否开启虚拟滚动"
"MultiSelectsAttribute_IsVirtualize": "是否开启虚拟滚动",
"MultiSelectsAttribute_DefaultVirtualizeItemText": "开启虚拟滚动时首次加载 Value 对应的文本字符串用逗号分割"
},
"BootstrapBlazor.Server.Components.Samples.Radios": {
"RadiosTitle": "Radio 单选框",
Expand Down Expand Up @@ -3208,7 +3209,8 @@
"SelectsOnInputChangedCallback": "编辑模式下输入文本转换为对应 Value 回调方法",
"TextConvertToValueCallback": "编辑模式下输入文本变化时回调方法",
"SelectsIsEditable": "是否可编辑",
"SelectsIsVirtualize": "是否开启虚拟滚动"
"SelectsIsVirtualize": "是否开启虚拟滚动",
"SelectsDefaultVirtualizeItemText": "开启虚拟滚动时首次加载 Value 对应的文本字符串用逗号分割"
},
"BootstrapBlazor.Server.Components.Samples.Sliders": {
"SlidersTitle": "Slider 滑块",
Expand Down
2 changes: 1 addition & 1 deletion src/BootstrapBlazor/BootstrapBlazor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>9.4.10</Version>
<Version>9.5.0-beta10</Version>
</PropertyGroup>

<ItemGroup>
Expand Down
34 changes: 29 additions & 5 deletions src/BootstrapBlazor/Components/Select/MultiSelect.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ public partial class MultiSelect<TValue>
[Parameter]
public Func<IEnumerable<SelectedItem>, Task>? OnSelectedItemsChanged { get; set; }

/// <summary>
/// Gets or sets the default virtualize items text.
/// </summary>
[Parameter]
public string? DefaultVirtualizeItemText { get; set; }

/// <summary>
/// 获得/设置 全选按钮显示文本
/// </summary>
Expand Down Expand Up @@ -158,6 +164,7 @@ public partial class MultiSelect<TValue>
[Parameter]
[NotNull]
public string? MinErrorMessage { get; set; }

[Inject]
[NotNull]
private IStringLocalizer<MultiSelect<TValue>>? Localizer { get; set; }
Expand All @@ -167,7 +174,7 @@ public partial class MultiSelect<TValue>
private string? ScrollIntoViewBehaviorString => ScrollIntoViewBehavior == ScrollIntoViewBehavior.Smooth ? null : ScrollIntoViewBehavior.ToDescriptionString();

/// <summary>
/// OnParametersSet 方法
/// <inheritdoc/>
/// </summary>
protected override void OnParametersSet()
{
Expand Down Expand Up @@ -195,15 +202,15 @@ protected override void OnParametersSet()
if (_lastSelectedValueString != _currentValue)
{
_lastSelectedValueString = _currentValue;
var list = _currentValue.Split(',', StringSplitOptions.RemoveEmptyEntries);

SelectedItems.Clear();
if (IsVirtualize)
{
SelectedItems.AddRange(list.Select(i => new SelectedItem(i, i)));
SelectedItems.AddRange(GetItemsByVirtualize());
}
else
{
var list = _currentValue.Split(',', StringSplitOptions.RemoveEmptyEntries);
SelectedItems.AddRange(Rows.Where(item => list.Any(i => i.Trim() == item.Value)));
}
}
Expand Down Expand Up @@ -232,6 +239,23 @@ protected override void OnAfterRender(bool firstRender)
ToggleRow = nameof(ToggleRow)
});

private List<SelectedItem> GetItemsByVirtualize()
{
var ret = new List<SelectedItem>();
var texts = new List<string>();
if (!string.IsNullOrEmpty(DefaultVirtualizeItemText))
{
texts.AddRange(DefaultVirtualizeItemText.Split(',', StringSplitOptions.RemoveEmptyEntries));
}
var values = CurrentValueAsString.Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
for (int i = 0; i < values.Count; i++)
{
var text = i < texts.Count ? texts[i] : values[i];
ret.Add(new SelectedItem(values[i], text));
}
return ret;
}

private int _totalCount;
private ItemsProviderResult<SelectedItem> _result;

Expand Down Expand Up @@ -265,7 +289,7 @@ protected override async Task OnClearValue()
}

/// <summary>
/// FormatValueAsString 方法
/// <inheritdoc/>
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
Expand Down Expand Up @@ -350,7 +374,7 @@ public async Task<bool> TriggerEditTag(string val)
val = val.Trim();
if (OnEditCallback != null)
{
ret = await OnEditCallback.Invoke(val);
ret = await OnEditCallback(val);
}
else if (!string.IsNullOrEmpty(val))
{
Expand Down
19 changes: 7 additions & 12 deletions test/UnitTest/Components/MultiSelectTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ public void IsMarkupString_Ok()
}

[Fact]
public void IsVirtualize_Items()
public void DefaultVirtualizeItemText_Ok()
{
var cut = Context.RenderComponent<MultiSelect<string>>(pb =>
{
Expand All @@ -677,19 +677,14 @@ public void IsVirtualize_Items()
new("1", "Test1"),
new("2", "Test2")
});
pb.Add(a => a.Value, "2");
pb.Add(a => a.Value, "1,2");
pb.Add(a => a.DefaultVirtualizeItemText, "Test1");
pb.Add(a => a.IsVirtualize, true);
pb.Add(a => a.RowHeight, 33f);
pb.Add(a => a.OverscanCount, 4);
});

cut.SetParametersAndRender(pb => pb.Add(a => a.ShowSearch, true));
cut.InvokeAsync(async () =>
{
// 搜索 T
cut.Find(".search-text").Input("T");
await cut.Instance.ConfirmSelectedItem(0);
});
var items = cut.FindAll(".multi-select-items .multi-select-item");
Assert.Equal(2, items.Count);
Assert.Equal("Test1", items[0].InnerHtml);
Assert.Equal("2", items[1].InnerHtml);
}

[Fact]
Expand Down