Tree.Expand delegate that is async #472

Closed
opened 2026-01-29 17:37:50 +00:00 by claunia · 4 comments
Owner

Originally created by @duanepfeiffer on GitHub (Jul 13, 2022).

Describe the bug
If your Expand delegate has an await and one of your tree items is expanded using Expanded delegate (ie expanded via code), children are not displayed.

To Reproduce
Make the following changes to the Tree->Files and directories demo
markup:
<RadzenTreeLevel Text=@GetTextForNode Template=@FileOrFolderTemplate
Expanded=@(n => Path.GetFileName((string)n) == "runtimes")/>
code:

  1. Make LoadFiles async Task
  2. Add await Task.Delay(2000)

Expected behavior
When app displays, the files in the runtimes folder should show.

Screenshots
Get:
image

Should Get:
image

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser Chrome
  • Version 3.19.4

Index.zip

Originally created by @duanepfeiffer on GitHub (Jul 13, 2022). <!-- IMPORTANT: Read this first!!! 1. If you own a Radzen Professional or Еnterprise subscription you can report your issue or ask us a question via email at info@radzen.com. Radzen staff will reply within 24 hours (Professional) or 16 hours (Enterprise) 2. The Radzen staff guarantees a response to issues in this repo only to paid subscribers. 3. If you have a HOW TO question start a new forum thread in the Radzen Community forum: https://forum.radzen.com. Radzen staff will close issues that are HOWTO questions. 4. Please adhere to the issue template. Specify all the steps required to reproduce the issue or link a project which reproduces it easily (without requiring extra steps such as restoring a database). --> **Describe the bug** If your Expand delegate has an await and one of your tree items is expanded using Expanded delegate (ie expanded via code), children are not displayed. **To Reproduce** Make the following changes to the Tree->Files and directories demo **_markup_**: <RadzenTreeLevel Text=@GetTextForNode Template=@FileOrFolderTemplate Expanded=@(n => Path.GetFileName((string)n) == "runtimes")/> **_code_**: 1. Make LoadFiles async Task 2. Add await Task.Delay(2000) **Expected behavior** When app displays, the files in the runtimes folder should show. **Screenshots** Get: ![image](https://user-images.githubusercontent.com/22204576/178831557-ed717a07-def0-4771-84f3-1225df66a4d0.png) Should Get: ![image](https://user-images.githubusercontent.com/22204576/178831642-ab3bff9b-1bf6-467c-8af5-367cdb11a08d.png) **Desktop (please complete the following information):** - OS: Windows 11 - Browser Chrome - Version 3.19.4 [Index.zip](https://github.com/radzenhq/radzen-blazor/files/9105950/Index.zip)
Author
Owner

@duanepfeiffer commented on GitHub (Jul 13, 2022):

Not sure if this is the correct way to fix this but for now I've added StateHasChanged to the bottom of ExpandItem in RadzenTree.razor.cs

    internal async Task ExpandItem(RadzenTreeItem item)
    {
        var args = new TreeExpandEventArgs()
        {
            Text = item?.Text,
            Value = item?.Value,
            Children = new TreeItemSettings()
        };

        await Expand.InvokeAsync(args);

        if (args.Children.Data != null)
        {
            Debug.WriteLine("<<RADZEN>> Rendering children...");

            var childContent = new RenderFragment(builder =>
            {
                Func<object, string> text = null;
                var children = args.Children;

                foreach (var data in children.Data)
                {
                    if (text == null)
                    {
                        text = children.Text ?? Getter<string>(data, children.TextProperty);
                    }

                    RenderTreeItem(builder, data, children.Template, text, children.HasChildren, children.Expanded, children.Selected);
                    builder.CloseComponent();
                }
            });

            item.RenderChildContent(childContent);

            if (AllowCheckBoxes && AllowCheckChildren && args.Children.Data != null)
            {
                if (CheckedValues != null && CheckedValues.Contains(item.Value))
                {
                    await SetCheckedValues(CheckedValues.Union(args.Children.Data.Cast<object>().Except(UncheckedValues)));
                }
                else
                {
                    await SetCheckedValues(CheckedValues.Except(args.Children.Data.Cast<object>()));
                }
            }
        }
        else if (item.Data != null)
        {
            if (AllowCheckBoxes && AllowCheckChildren && item.Data != null)
            {
                if (CheckedValues != null && CheckedValues.Contains(item.Value))
                {
                    await SetCheckedValues(CheckedValues.Union(item.Data.Cast<object>().Except(UncheckedValues)));
                }
                else
                {
                    await SetCheckedValues(CheckedValues);
                }
            }
        }
        **this.StateHasChanged();**
    }
@duanepfeiffer commented on GitHub (Jul 13, 2022): Not sure if this is the correct way to fix this but for now I've added StateHasChanged to the bottom of ExpandItem in RadzenTree.razor.cs internal async Task ExpandItem(RadzenTreeItem item) { var args = new TreeExpandEventArgs() { Text = item?.Text, Value = item?.Value, Children = new TreeItemSettings() }; await Expand.InvokeAsync(args); if (args.Children.Data != null) { Debug.WriteLine("<<RADZEN>> Rendering children..."); var childContent = new RenderFragment(builder => { Func<object, string> text = null; var children = args.Children; foreach (var data in children.Data) { if (text == null) { text = children.Text ?? Getter<string>(data, children.TextProperty); } RenderTreeItem(builder, data, children.Template, text, children.HasChildren, children.Expanded, children.Selected); builder.CloseComponent(); } }); item.RenderChildContent(childContent); if (AllowCheckBoxes && AllowCheckChildren && args.Children.Data != null) { if (CheckedValues != null && CheckedValues.Contains(item.Value)) { await SetCheckedValues(CheckedValues.Union(args.Children.Data.Cast<object>().Except(UncheckedValues))); } else { await SetCheckedValues(CheckedValues.Except(args.Children.Data.Cast<object>())); } } } else if (item.Data != null) { if (AllowCheckBoxes && AllowCheckChildren && item.Data != null) { if (CheckedValues != null && CheckedValues.Contains(item.Value)) { await SetCheckedValues(CheckedValues.Union(item.Data.Cast<object>().Except(UncheckedValues))); } else { await SetCheckedValues(CheckedValues); } } } **this.StateHasChanged();** }
Author
Owner

@akorchev commented on GitHub (Jul 14, 2022):

This is what happens with this code:

    async Task LoadFiles(TreeExpandEventArgs args)
    {
        var directory = args.Value as string;

        await Task.Delay(2000);
        args.Children.Data = Directory.EnumerateFileSystemEntries(directory);
        args.Children.Text = GetTextForNode;
        args.Children.HasChildren = (path) => Directory.Exists((string)path);
        args.Children.Template = FileOrFolderTemplate;
    }

tree

The nodes appear after a delay without having an extra StateHasChanged() call.

@akorchev commented on GitHub (Jul 14, 2022): This is what happens with this code: ``` async Task LoadFiles(TreeExpandEventArgs args) { var directory = args.Value as string; await Task.Delay(2000); args.Children.Data = Directory.EnumerateFileSystemEntries(directory); args.Children.Text = GetTextForNode; args.Children.HasChildren = (path) => Directory.Exists((string)path); args.Children.Template = FileOrFolderTemplate; } ``` ![tree](https://user-images.githubusercontent.com/454726/178966182-0f61673c-3d4d-4b35-b732-802530f8c0be.gif) The nodes appear after a delay without having an extra StateHasChanged() call.
Author
Owner

@duanepfeiffer commented on GitHub (Jul 14, 2022):

Your example is showing user click to expand? That is not the way to reproduce the problem. Did you change your html markup as described in my post?

<RadzenTreeLevel Text=@GetTextForNode Template=@FileOrFolderTemplate
Expanded=@(n => Path.GetFileName((string)n) == "wwwroot")/>

@duanepfeiffer commented on GitHub (Jul 14, 2022): Your example is showing user click to expand? That is not the way to reproduce the problem. Did you change your html markup as described in my post? <RadzenTreeLevel Text=@GetTextForNode Template=@FileOrFolderTemplate **Expanded=@(n => Path.GetFileName((string)n) == "wwwroot")**/>
Author
Owner

@akorchev commented on GitHub (Jul 15, 2022):

I see. Should be fixed by d6760ca4b9

@akorchev commented on GitHub (Jul 15, 2022): I see. Should be fixed by d6760ca4b9ddc7ea42f8bb830a0263e58b048cf7
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/radzen-blazor#472