Dynamic Grid with Multiple Selections

Currently I have a datagrid utilizing dynamic data based on the sample found at Blazor DataGrid Component - Dynamic Data | Free UI Components by Radzen. I am now trying to add in the multiple-selection capabilities as found in the sample Blazor DataGrid Component - Multiple Selection | Free UI Components by Radzen.

Are there any good examples of combining the two? I can select individual rows without issues, however, I am running into issues with the "select all" checkbox in the header. Using the code “out of the box” from the samples listed above (and adjusting the variable names), the header checkbox isn’t displaying as it should. If I click the “Select All” checkbox, it gives me the partial list indicator (dash) and none of the checkboxes for individual items get selected. I can then not unselect the “select all” checkbox. It’s stuck.

The data side is "almost" accurate though, as I am able to capture that the rows are indeed added/removed from my “gridSelections” variable. However, if I use the header checkbox to try and remove all selections, nothing is removed from the list and the indicator is stuck in the "partial" indicator.


<RadzenDataGrid @ref="grid"       AllowRowSelectOnRowClick="@allowRowSelectOnRowClick" SelectionMode="DataGridSelectionMode.Multiple"       Count="@gridCount" @bind-Value="@gridSelections" Data="@gridData" TItem="IDictionary<string, object>" Visible="@gridVisible" IsLoading="@loading" FilterMode="FilterMode.Advanced" FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive" PageSizeOptions=@(new int[]{20, 50, 100, 250, 500, 1000}) AllowFiltering="@DynGrid.GetGridPropertyAllowFiltering(dynGridConfig)" AllowPaging="@DynGrid.GetGridPropertyAllowPaging(dynGridConfig)" AllowSorting="@DynGrid.GetGridPropertyAllowSorting(dynGridConfig)" ShowPagingSummary="@DynGrid.GetGridPropertyShowPagingSummary(dynGridConfig)" PageSize="@DynGrid.GetGridPropertyPageSize(dynGridConfig)" AllowColumnResize="@DynGrid.GetGridPropertyAllowColumnResize(dynGridConfig)" AllowGrouping="@DynGrid.GetGridPropertyAllowGrouping(dynGridConfig)" AllGroupsExpanded="@DynGrid.GetGridPropertyAllGroupsExpanded(dynGridConfig)" AllowColumnPicking="@DynGrid.GetGridPropertyAllowColumnPicking(dynGridConfig)" ColumnsPickerAllowFiltering="@DynGrid.GetGridPropertyColumnsPickerAllowFiltering(dynGridConfig)" Style="@DynGrid.GetGridPropertyStyle(dynGridConfig)" class="no-radzen-load-indicator">
	<EmptyTemplate>
		<p class="emptymessage-text">No records to display.</p>
	</EmptyTemplate>

	<Columns>


		<RadzenDataGridColumn Width="60px" Sortable="false" Filterable="false" Groupable="false" Pickable="false" TextAlign="TextAlign.Center">
			<HeaderTemplate>
				<RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select all items" }})"
								Value="@(gridSelections == null || gridSelections?.Any() != true ? false : !gridData.All(i => gridSelections.Contains(i)) ? null : gridData.Any(i => gridSelections.Contains(i)))"
								Change="@(args => gridSelections = args == true ? gridData.ToList() : null)" />
			</HeaderTemplate>
			<Template Context="data">
				<RadzenCheckBox TabIndex="-1" TriState="false" Value="@(gridSelections != null && gridSelections.Contains(data))" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select item" }})"
								TValue="bool" Change=@(args => { if(!allowRowSelectOnRowClick) { grid.SelectRow(data); }}) />
			</Template>
		</RadzenDataGridColumn>


		@if (columns != null)
		{
			foreach (var column in columns)
			{
				<RadzenDataGridColumn @key=@column.Key Type="column.Value" Property="@PropertyAccess.GetDynamicPropertyExpression(column.Key, column.Value)" Title="@DynGrid.GetColumnPropertyTitle(column.Key, dynGridCols)" OrderIndex="@DynGrid.GetColumnPropertyOrderIndex(column.Key, dynGridCols)" Visible="@DynGrid.GetColumnPropertyVisible(column.Key, dynGridCols)" Pickable="@DynGrid.GetColumnPropertyPickable(column.Key, dynGridCols)" Frozen="@DynGrid.GetColumnPropertyFrozen(column.Key, dynGridCols)" Sortable="@DynGrid.GetColumnPropertySortable(column.Key, dynGridCols)" Filterable="@DynGrid.GetColumnPropertyFilterable(column.Key, dynGridCols)" Groupable="@DynGrid.GetColumnPropertyGroupable(column.Key, dynGridCols)" Resizable="@DynGrid.GetColumnPropertyResizable(column.Key, dynGridCols)" CssClass="@DynGrid.GetColumnPropertyCssClass(column.Key, dynGridCols)" Width="@DynGrid.GetColumnPropertyWidth(column.Key, dynGridCols)" MinWidth="@DynGrid.GetColumnPropertyMinWidth(column.Key, dynGridCols)">
					<Template Context="contextColumn">
						<div class="text-wrapper">@contextColumn[@column.Key]</div>
					</Template>
				</RadzenDataGridColumn>
			}
		}
	</Columns>
</RadzenDataGrid>


<RadzenButton ButtonStyle="ButtonStyle.Primary" Icon="edit" Text="Bulk Edit" Click="@(args => UpdateSelection())" />


@code {
	bool allowRowSelectOnRowClick = true;

	public async Task UpdateSelection()
	{
		var testVal = gridSelections;

	}
}

Here is a working example based on both demos:

<RadzenDataGrid @ref="grid" AllowRowSelectOnRowClick="false" SelectionMode="DataGridSelectionMode.Multiple" @bind-Value=@selectedItems Data="@data" TItem="IDictionary<string, object>" ColumnWidth="200px"
                AllowFiltering="true" FilterPopupRenderMode="PopupRenderMode.OnDemand" FilterMode="FilterMode.Advanced" AllowPaging="true" AllowSorting="true">
    <Columns>
        <RadzenDataGridColumn Width="60px" Sortable="false" Filterable="false">
            <HeaderTemplate>
                <RadzenCheckBox TabIndex="-1" TriState="false" TValue="bool?" 
                   Value="@(selectedItems == null || selectedItems?.Any() != true ? false : !data.All(i => selectedItems.Contains(i)) ? null : data.Any(i => selectedItems.Contains(i)))"
                   Change="@(args => selectedItems = args == true ? data.ToList() : null)" />
            </HeaderTemplate>
            <Template Context="data">
                <RadzenCheckBox TabIndex="-1" TriState="false" Value="@(selectedItems != null && selectedItems.Contains(data))" 
                    TValue="bool" Change=@(args => grid.SelectRow(data)) />
            </Template>
        </RadzenDataGridColumn>

        @foreach (var column in columns)
        {
            <RadzenDataGridColumn @key=@column.Key Title="@column.Key" Type="column.Value"
                                  Property="@PropertyAccess.GetDynamicPropertyExpression(column.Key, column.Value)">
                <Template>
                    @context[@column.Key]
                </Template>
            </RadzenDataGridColumn>
        }
    </Columns>
</RadzenDataGrid>

@code {
    RadzenDataGrid<IDictionary<string, object>> grid;
    IList<IDictionary<string, object>> selectedItems;

    public IEnumerable<IDictionary<string, object>> data { get; set; }

    public IDictionary<string, Type> columns { get; set; }

    public enum EnumTest
    {
        EnumValue1,
        EnumValue2
    }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        columns = new Dictionary<string, Type>()
        {
            { "Employee ID", typeof(int?) },
            { "MyColumn", typeof(EnumTest?) },
            { "FirstName", typeof(string) },
            { "LastName", typeof(string) },
            { "HireDate", typeof(DateTime?) },
            { "DateOnly", typeof(DateOnly?) },
            { "TimeOnly", typeof(TimeOnly?) },
            { "UID", typeof(Guid?) },
        };

        foreach (var i in Enumerable.Range(0, 50))
        {
            columns.Add($"Column{i}", typeof(string));
        }

        data = Enumerable.Range(0, 100).Select(i =>
        {
            var row = new Dictionary<string, object>();

            foreach (var column in columns)
            {
                row.Add(
                    column.Key,
                    column.Value == typeof(EnumTest?)
                        ? i == 0 ? null : (i % 2 == 0 ? EnumTest.EnumValue1 : EnumTest.EnumValue2)
                        : column.Value == typeof(int?)
                            ? i == 0 ? null : i
                            : column.Value == typeof(DateTime?)
                                ? i == 0 ? null : DateTime.Now.AddMonths(i)
                                : column.Value == typeof(Guid?)
                                ? i == 0 ? null : Guid.NewGuid()
                                : column.Value == typeof(DateOnly?)
                                ? i == 0 ? null : DateOnly.FromDateTime(DateTime.Now.AddMonths(i))
                                : column.Value == typeof(TimeOnly?)
                                ? i == 0 ? null : TimeOnly.FromDateTime(DateTime.Now.AddMonths(i))
                                : $"{column.Key}{i}" 
                );
            }

            return row;
        }).ToList();
    }
}
1 Like