Hi @enchev,
thanks for looking into my issue. I've seen that, but I'm afraid I don't really understand how that helps me if the internal checked state seems to be reset.
Maybe you could help me out with some advice?
To demonstrate my problem I created a small example:
@page "/treecheck"
@using System.Collections
@using System.ComponentModel.DataAnnotations
@using Radzen
@using Radzen.Blazor
@inherits TreeCheckBase
<RadzenTree @ref="dataTree" Data=@treeItems
AllowCheckBoxes="true"
AllowCheckChildren="true"
AllowCheckParents="true"
CheckedValuesChanged=@CheckedValuesChanged
Expand=@LoadTreeFiles
Change=@OnSelectionChange
ItemRender="@TreeItemRender">
<RadzenTreeLevel Text=@GetTextForTreeNode Template=@TreeTemplate ChildrenProperty="Children" Expanded=@ShouldExpand HasChildren=HasChildren />
</RadzenTree>
using Microsoft.AspNetCore.Components;
using Radzen;
using Radzen.Blazor;
namespace TabsIssue.Components.Pages
{
public class TreeModel
{
public string DataElementId { get; set; }
public string Name { get; set; }
public bool IsGroup { get; set; }
}
public class TreeItem<T>
{
public T Item { get; set; }
public IEnumerable<TreeItem<T>> Children { get; set; }
public bool? Checked { get; set; }
public bool Expanded { get; set; }
}
public class TreeCheckBase : ComponentBase
{
protected RadzenTree dataTree;
protected List<TreeItem<TreeModel>> treeItems;
protected override async Task OnInitializedAsync()
{
treeItems = new();
treeItems.Add(new TreeItem<TreeModel>
{
Item = new TreeModel { DataElementId = "1", Name = "Root", IsGroup = true },
Children = new List<TreeItem<TreeModel>>
{
new TreeItem<TreeModel>
{
Item = new TreeModel { DataElementId = "2", Name = "Child 1", IsGroup = false },
Children = new List<TreeItem<TreeModel>>
{
new TreeItem<TreeModel>
{
Item = new TreeModel { DataElementId = "3", Name = "Child 1.1", IsGroup = false },
Children = new List<TreeItem<TreeModel>>()
},
new TreeItem<TreeModel>
{
Item = new TreeModel { DataElementId = "4", Name = "Child 1.2", IsGroup = false },
Children = new List<TreeItem<TreeModel>>()
}
}
},
new TreeItem<TreeModel>
{
Item = new TreeModel { DataElementId = "4", Name = "Child 2", IsGroup = false },
Children = new List<TreeItem<TreeModel>>()
}
}
});
await base.OnInitializedAsync();
}
protected void LoadTreeFiles(TreeExpandEventArgs args)
{
var selected = args.Value as TreeItem<TreeModel>;
args.Children.Data = selected.Children;
args.Children.Text = GetTextForTreeNode;
args.Children.HasChildren = (path) =>
{
if (path is TreeItem<TreeModel> treeNode)
{
if (treeNode.Children != null)
{
return treeNode.Children.Any();
}
}
return false;
};
args.Children.Template = TreeTemplate;
}
protected async Task CheckedValuesChanged(IEnumerable<object> selectedItems)
{
var checkedIds = selectedItems.Select(ti =>
{
return (ti as TreeItem<TreeModel>).Item.DataElementId;
}).ToList();
var checkedItems = selectedItems.Select(ti => ti as TreeItem<TreeModel>).ToList();
}
protected async Task OnSelectionChange()
{
}
protected void TreeItemRender(TreeItemRenderEventArgs args)
{
if (args.Value is TreeItem<TreeModel> treeItem)
{
//bool? checkedState = TreeHelper.CheckedChildren(treeItem);
//args.Checked = checkedState;
}
}
protected RenderFragment<RadzenTreeItem> TreeTemplate = (context) => builder =>
{
TreeItem<TreeModel> path = context.Value as TreeItem<TreeModel>;
bool isDirectory = false;
if (path is TreeItem<TreeModel> treeNode)
{
isDirectory = treeNode.Item.IsGroup;
}
builder.OpenComponent<RadzenIcon>(0);
builder.AddAttribute(1, nameof(RadzenIcon.Icon), isDirectory ? "folder" : "insert_drive_file");
builder.CloseComponent();
builder.AddContent(2, context.Text);
};
protected string GetTextForTreeNode(object data)
{
return (data as TreeItem<TreeModel>).Item.Name;
}
protected bool ShouldExpand(object data)
{
if (data is TreeItem<TreeModel> treeItem)
{
var expanded = treeItem.Expanded;
return expanded;
}
return false;
}
protected bool HasChildren(object data)
{
if (data is TreeItem<TreeModel> treeItem)
{
var hasChildren = treeItem.Children.Any();
return hasChildren;
}
return false;
}
}
}
Would you mind trying the following?
- expand Root
- expand Child1
- check Child 1.2
- collapse Child1
- expand Child1
The selectedItems of the CheckedValuesChanged callback is now an empty list. And Child 1.2 is unchecked.
If you do the same procedure, but in step 3 check both children, everything works as I wish.
Is this expected behaviour?
Thanks again for your support!
Cheers and best!