Cannot get child properties in TreeGrid column templates

Good morning,

I want to show a list of BusinessObject into a TreeGrid view:

    public class BusinessObject
    {
        public string TaskId { get; set; }
        public string TaskName { get; set; }
        public string? ParentId { get; set; }
        public MyParentClass AnyChild { get; set; }
    }

The last member is a reference to an object of a parent class:

    public class MyParentClass
    {
        public string ActualType;
    }

I have defined two children from this class:

    public class MyFirstChildClass : MyParentClass
    {
        public string MyFirstChildString { get; set; }
    }

    public class MySecondChildClass : MyParentClass
    {
        public string MySecondChildString { get; set; }
    }

I then added the elements to the list that I want to show. For instance:

MyFirstChildClass myCustomChild1 = new MyFirstChildClass() { ActualType = "MyFirstChildClass", MyFirstChildString = "testString1" };
TreeData.Add(new BusinessObject() { TaskId = "1", TaskName = "Parent Task 1", ParentId = null, AnyChild = myCustomChild1 });

Now I try to render the TreeGrid:

<SfTreeGrid DataSource="@TreeData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="0">
    <TreeGridColumns>
        <TreeGridColumn Field="TaskId" HeaderText="Task ID" Width="5" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center"></TreeGridColumn>
        <TreeGridColumn Field="TaskName" HeaderText="Task Name" Width="30" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center"></TreeGridColumn>
        <TreeGridColumn HeaderText="Child String" Width="30" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center">
            <Template>
                @{
                    BusinessObject bo = context as BusinessObject;


                    if(bo is not null)
                    {
                        // The following line does not work, bo.AnyChild is not correctly recognized as an instance of MyFirstChildClass
                        if (bo.AnyChild is MyFirstChildClass c1)
                        {
                            @c1.MyFirstChildString;
                        }
                        // The following line does not work, bo.AnyChild is not correctly recognized as an instance of MyChildClass
                        else if(bo.AnyChild is MySecondChildClass c2)
                        {
                            @c2.MySecondChildString;
                        }
                        else
                        {
                            @:<span>String not found!</span>
                        }
                    }
                }
            </Template>
        </TreeGridColumn>
    </TreeGridColumns>
</SfTreeGrid>

I expect to see the third column (the one with the template) with the values "testString1", but I only see "String not found!". How can I solve this problem?

I add the sample project where you can reproduce the issue.


Attachment: TreeGridDemo_e87406fc.zip

6 Replies

PS Pon Selva Jeganathan Syncfusion Team May 6, 2022 01:38 PM UTC

Hi Alessandro,


Thanks for contacting syncfusion forum.


Query: I expect to see the third column (the one with the template) with the values "testString1", but I only see "String not found!". How can I solve this problem?


We checked your shared sample; we were able to reproduce the issue at our end.  In your shared sample, the child value (ActualType) is always got null. So this issue occurred.


To avoid this issue, we suggest you follow the below code example,


 

Your code:

 

 

<SfTreeGrid DataSource="@TreeData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="0">

    …..

        <TreeGridColumn HeaderText="Child String" Width="30" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center">

            <Template>

                @{

                    BusinessObject bo = context as BusinessObject;

 

                    if(bo is not null)

                    {

                        // The following line does not work, bo.AnyChild is not correctly recognized as an instance of MyFirstChildClass

                        if (bo.AnyChild is MyFirstChildClass c1)

                        {

                            @c1.MyFirstChildString;

                        }

                        // The following line does not work, bo.AnyChild is not correctly recognized as an instance of MyChildClass

                        else if(bo.AnyChild is MySecondChildClass c2)

                        {

                            @c2.MySecondChildString;

                        }

                        else

                        {

                            @:<span>String not found!</span>

                        }

                    }

                }

            </Template>

        </TreeGridColumn>

    </TreeGridColumns>

</SfTreeGrid>

 

@code

{

    public class MyParentClass

    {

        public string ActualType;

    }

 

    public class MyFirstChildClass : MyParentClass

    {

        public string MyFirstChildString { get; set; }

    }

 

    public class MySecondChildClass : MyParentClass

    {

       public string MySecondChildString { get; set; }

    }

 

 

 

Modified Code:

 

<SfTreeGrid DataSource="@TreeData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="0">

    ….. TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center">

            <Template>

                @{

                    BusinessObject bo = context as BusinessObject;

 

                    if(bo.AnyChild is not null)

                    {

                        // The following line does not work, bo.AnyChild is not correctly recognized as an instance of MyFirstChildClass

                        if (bo.AnyChild.ActualType == "MyFirstChildClass" )

                        {

                           

                            @bo.AnyChild.MyFirstChildString;

                        }

                        // The following line does not work, bo.AnyChild is not correctly recognized as an instance of MyChildClass

                        else if(bo.AnyChild.ActualType == "MySecondChildClass")

                        {

                            @bo.AnyChild.MySecondChildString;

                        }

                        else

                        {

                            @:<span>String not found!</span>

                        }

                       // @bo.AnyChild.ActualType;

                    }

                }

            </Template>

        </TreeGridColumn>

    </TreeGridColumns>

</SfTreeGrid>

 

@code

{

    public class MyParentClass

    {

        public string? ActualType { get; set; }

        public string? MyFirstChildString { get; set; }

        public string? MySecondChildString { get; set; }

       

    }

 

    public class MyFirstChildClass : MyParentClass

    {

        public string? MyFirstChildString1 { get; set; }

    }

 

    public class MySecondChildClass : MyParentClass

    {

        public string? MySecondChildString1 { get; set; }

    }


Please refer to the below screenshot,


Please refer to the below modified sample,

https://www.syncfusion.com/downloads/support/directtrac/general/ze/TreeGridDemo-1636130135


Kindly get back to us for further assistance.


Regards,  

Pon selva   




AC Alessandro Chillemi May 7, 2022 04:23 PM UTC

Good morning and thanks for the reply.

Unfortunately your workaround is not a solution to my problem. I have many child classes and I cannot copy all their attributes into the parent class: if I could do that, then I wouldn't need child classes.

In your shared sample, the child value (ActualType) is always got null. So this issue occurred.

Why the child value was null inside the component? This looks like a bug to me. I would like to get the child objects correctly, as they were created. Is it possible to solve this issue?



PS Pon Selva Jeganathan Syncfusion Team May 9, 2022 02:04 PM UTC

Hi Alessandro,


Thanks for the update.


We are working on this query with high priority. And we need time to feasible solution of your requirement and will update you with further details on or before 11th May 2022.  Until then we value your patience.


Meanwhile we will contact you if any details required.  


Regards,  

Pon selva   




PS Pon Selva Jeganathan Syncfusion Team May 11, 2022 02:59 PM UTC

Hi Alessandro,


Sorry for the inconvenience caused.


We are working on this query with high priority. And we need time to validate the issue at our end and will update you with further details on or before 13th May 2022.  Until then we value your patience.


Regards,  

Pon selva   




PS Pon Selva Jeganathan Syncfusion Team May 13, 2022 02:36 PM UTC

Hi Alessandro,


On further validation, we have considered the reported issue (Cannot get child properties in Treegrid column template”) as a bug. Thank you for taking the time to report this issue and helping us improve our product. At Syncfusion, we are committed to fixing all validated defects (subject to technological feasibility and Product Development Life Cycle) and will include the fix in our upcoming patch release which is expected to be rolled out on 1st June 2022. Until then we appreciate your patience.


You can now track the current status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link. 

https://www.syncfusion.com/feedback/34894/cannot-get-child-properties-in-treegrid-column-template


Note: To view the above feedback, kindly login into your account. 


Regards,
Pon selva




MP Manivannan Padmanaban Syncfusion Team May 25, 2022 08:56 AM UTC

Hi Alessandro,


We appreciate your patience.


Upon on validation, we could see that source level fixing is not feasible for the reported issue. Since tree grid doesn’t know the information of the extended classes, the tree grid will know only the properties of BusinessObject class(data source class). And in BusinessObject class you have defined the sub class as MyParentClass in that you have defined only ActualType from that we cannot retrieve all the extended class properties.


So, we suggest you define the properties in MyParentClass and since its not work in your case because of many children definition. Hence, we suggest you use the ExpandoObject class as like below,


<SfTreeGrid DataSource="@TreeData" IdMapping="TaskId" ParentIdMapping="ParentId" TreeColumnIndex="0">

    <TreeGridColumns>

…………………………………..

            <Template>

                @{

                    BusinessObject bo = context as BusinessObject;

 

                    if (bo is not null)

                    {

                       

                        if (bo.AnyChild is ExpandoObject)

                        {

                            var data = (bo.AnyChild as IDictionary<string, object>);

                            if ((bo.AnyChild as IDictionary<string, object>)["ActualType"].ToString() == "MyFirstChildClass")

                            {

                                @((bo.AnyChild as IDictionary<string, object>)["MyFirstChildString"]);

                            }

                            else if ((bo.AnyChild as IDictionary<string, object>)["ActualType"].ToString() == "MySecondChildClass")

                            {

                                @((bo.AnyChild as IDictionary<string, object>)["MySecondChildString"]);

                            }

                            else

                            {

                                @:<span>String not found!</span>

                            }

                        }

                    }

                }

            </Template>

        </TreeGridColumn>

    </TreeGridColumns>

</SfTreeGrid>

 

@code

{

 

    public class BusinessObject

    {

        public string TaskId { get; set; }

        public string TaskName { get; set; }

        public string? ParentId { get; set; }

        public ExpandoObject AnyChild { get; set; }

    }

 

    public List<BusinessObject> TreeData = new List<BusinessObject>();

 

    protected override void OnInitialized()

    {

        dynamic Task1 = new ExpandoObject();

        Task1.ActualType = "MyFirstChildClass";

        Task1.MyFirstChildString = "testString1";

 

        dynamic Task2 = new ExpandoObject();

        Task2.ActualType = "MySecondChildClass";

        Task2.MySecondChildString = "testString2";

 

        TreeData.Add(new BusinessObject() { TaskId = "1", TaskName = "Parent Task 1", ParentId = null, AnyChild = Task1 });

        TreeData.Add(new BusinessObject() { TaskId = "2", TaskName = "Child task 1", ParentId = "1", AnyChild = Task2 });

    }

}


Output


Chart

Description automatically generated with medium confidence


Kindly get back to us if you need any further assistance. We will be happy to assist you.


Regards,

Manivannan Padmanaban


Loader.
Up arrow icon