RadzenTree - Checked Values Not There Until Rendered

Hi,

Is there a way to get all checked values for a multi-level tree without rendering all of the children?

In the example below, I have bound the checked values of the tree using
@bind-CheckedValues. I display all of the names of the checked values in a text box.

When selecting the parent while using AllowCheckChildren=true, only the parent's name shows up in the text but until I expand the children.

Checked Items Radzen Tree

There is a demo showing how to handle this using ItemRender event:

Hi Enchev,

The ItemRender event does not help me because the children are not rendered when the parent is selected.

Selecting the parent node in the example above selects both the parent and all of its children. I would expect the children and the parent to be added to the CheckedValues list without having to render them.

Currently only the parent is added to the CheckedValues list when clicked because it is the only node that is render. The children are not added, but do get added after they are rendered by clicking the expand arrow.

Is there a way to get the full CheckedValues list without having rending any of the children?

1 Like

The idea of the example is to show how to set parent checked state knowing what is the checked state of the children without expanding them.

Hi Enchev,

What I am trying to understand is when a user clicks on a parent node that also checks all of its children why it does not add all of the children to the CheckedValues list until the children are rendered.

Below is a direct example of the behavior using the link you sent me.

Notice that when "Beverages" is select, the console only logs "Beverages" even though it checks all of its children. Notice that when I expand beverages, the console logs "Beverages" and all of its children now.

Is there a way to add all of Beverages children to the CheckedValues list without rendering the children or doing it manually.

Recording 2024-05-16 125347

To reproduce this on your side, I slightly modified the source, removing the manual assignment of CheckedValues in OnInitializedAsync and removed the ItemRender function and event.

@using Microsoft.EntityFrameworkCore
@using RadzenBlazorDemos.Models.Northwind

@inherits DbContextPage

<div class="container-fluid">
    <div class="row my-5">
        <div class="col-lg-6 offset-lg-3">
            <RadzenCard>
                <RadzenTree AllowCheckBoxes="true" @bind-CheckedValues=@CheckedValues Style="width: 100%; height: 300px" Data=@categories>
                    <RadzenTreeLevel TextProperty="CategoryName" ChildrenProperty="Products" />
                    <RadzenTreeLevel TextProperty="ProductName" HasChildren=@(product => false) />
                </RadzenTree>
            </RadzenCard>
        </div>
    </div>
</div>

<EventConsole @ref=@console />

@code {
    IEnumerable<Category> categories;
    IEnumerable<object> checkedValues;

    IEnumerable<object> CheckedValues
    {
        get => checkedValues;
        set
        {
            checkedValues = value;
            if (checkedValues != null)
            {
                console.Log($"CheckedValues Changed {string.Join(Environment.NewLine, value.Select(GetText))}");
            }
        }
    }

    string GetText(object data)
    {
        if (data is Category category)
        {
            return category.CategoryName;
        }

        if (data is Product product)
        {
            return product.ProductName;
        }

        return string.Empty;
    }

    EventConsole console;

    Category firstCategory;

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

        categories = await Task.FromResult(dbContext.Categories.Include(c => c.Products));

        firstCategory = await Task.FromResult(categories.FirstOrDefault());
    }
}

The children don’t exist until they are expanded.

So in the case where a user clicks the parents and does not render the children, then how is the developer supposed to captured all of the values that the user expects to be checked?

Whether or not they are rendered, the checked value of the children to the user still exist and the fact they are not captured by the CheckedValues list is a limitation to the developer.

Can you provide a recommendation on how capture these values?

If not, is there someone else I can speak to about this issue?

I already provided information twice about ItemRender event. I am afraid I cannot add anything else.

Hi Enchev,

I have already explained why the ItemRender event handler does not help.

If you cannot provide a recommendation, then is there someone on your team who can assist?

RadzenTree does not provide any means to "check" values that are not yet loaded. Frankly I don't think any component does. The problem is that if the values are not loaded they can't appear in the CheckedValues collection. You have to use your API to update that collection with values that are not yet loaded. Something like this:

<RadzenTree AllowCheckBoxes="true" @bind-CheckedValues=@CheckedValues 

@bind-CheckedValues:after="@UpdateCheckedValues" />


void UpdateCheckedValues()
{
   var children = CheckedValues.SelectMany(parent => GetChildrenForParent(parent));

   CheckedValues = CheckedValues.Concat(children);
}

Hi Korchev,

Thank you, that is helpful. Looking at the RadzenTreeItem.razor.cs, I see that the GetAllChildValues method uses the parameter List<RadzenTreeItem> items to determine the children when the CheckedChange method is run.

I submitted a pull request demonstrating minor change to both RadzenTree and RadzenTreeItem which now gets the children from the Value property rather than the Items. This now adds all children to the CheckedValues list regardless of whether or not the children are rendered.

If you could take a look and let me know if you see any problems, that would be great.

I am not sure what this PR does. You didn't provide any examples or a use case.

Hi Korchev,

I have updated the pull request with what the pull request is aimed to do as well as a video of the use case.