Two-way data binding in TreeGrid - gives compile error

Hi All,

As you can see below when you drag Child 2 to Parent2 the grid updates, but not the underlying Datasource. My goal is to have the Datasource -- List<TreeGridItem> updated to the same state as the what the TreeGrid is. The below screenshot shows that the different states after I dropped Child2 onto Parent2.

I assume that I need to utilise two-way data binding on a TreeGrid to allow this. When I use the @bind-Datasource attribute I get the following error. 

cannot convert from 'Microsoft.AspNetCore.Components.EventCallback<System.Collections.Generic.List<sfTestBed.Client.Pages.TreeGrid.TreeGridItem>>' to 'Microsoft.AspNetCore.Components.EventCallback'

Is there another way to achieve this?


@if (DataSource == null)
{
   <p>Loading ... please wait.....</p>
}
else
{
    <SfTreeGrid @ref="treeGrid" @bind-DataSource="@DataSource" TValue="TreeGridItem" 
 IdMapping="Id" ParentIdMapping="ParentId" HasChildMapping="IsParent" ExpandStateMapping="IsExpanded" TreeColumnIndex="1"
                AllowFiltering="true" AllowPaging="true" AllowSorting="true" AllowRowDragAndDrop="true"
                Toolbar="@(new List<string>() { "Add", "Edit", "Delete" })" Height="100%">
        <TreeGridPageSettings PageSize="3"></TreeGridPageSettings>
        <TreeGridEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true" Mode="Syncfusion.Blazor.TreeGrid.EditMode.Dialog"></TreeGridEditSettings>
        <TreeGridFilterSettings Type="Syncfusion.Blazor.TreeGrid.FilterType.Menu"></TreeGridFilterSettings>
        <TreeGridColumns>
            <TreeGridColumn Field="Id" HeaderText="Id" Width="80" IsPrimaryKey="true" Visible="true" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right"></TreeGridColumn>
            <TreeGridColumn Field="Name" HeaderText="Name" Width="240"></TreeGridColumn>
            <TreeGridColumn Field="ParentId" HeaderText="Pid" Width="240" Visible="true"></TreeGridColumn>
        </TreeGridColumns>
    </SfTreeGrid>

}

@code {
    [Parameter] public List<TreeGridItem> DataSource { get; set; }
    protected SfTreeGrid<TreeGridItem> treeGrid;

    protected override void OnInitialized()
    {
        DataSource = TreeGridItem.GetSampleData();
        base.OnInitialized();
    }

    protected void DataSourceChanged(IEnumerable<TreeGridItem> args)
    {
        foreach (var tgi in args)
        {
            Console.WriteLine($"Updated: {tgi.Id} - {tgi.Name} - {tgi.ParentId}");
        }
    }

    public class TreeGridItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? ParentId { get; set; }
        public bool IsParent { get; set; } = false;
        public bool IsExpanded { get; set; } = false;
        public static List<TreeGridItem> GetSampleData()
        {
            return new List<TreeGridItem>()
                {
                    new TreeGridItem
                    {
                        Id = 1,
                        Name = "Parent",
                        IsParent = true,
                        IsExpanded = true }
                    ,
                    new TreeGridItem
                    {
                        Id = 2,
                        Name = "Child1",
                        ParentId = 1,
                        IsParent = false,
                        IsExpanded = true }
                    ,
                    new TreeGridItem
                    {
                        Id = 3,
                        Name = "Child2",
                        ParentId = 1,
                        IsParent = false,
                        IsExpanded = true }
                    ,
                    new TreeGridItem
                    {
                        Id = 4,
                        Name = "Parent 2",
                        IsParent = false,
                        IsExpanded = true }

                };
        }
    }
}

5 Replies 1 reply marked as answer

PK Padmavathy Kamalanathan Syncfusion Team January 21, 2021 02:16 PM UTC

Hi Basil, 
 
Thanks for contacting Syncfusion Forums. 
 
Query: Two-way data binding in TreeGrid - gives compile error 
 
We have validated the reported issue at our end. The reported issue occurs when we use @bind-DataSource property with Tree Grid.  There is no need to use Two way binding property for  updating the Tree Grid data source after performing Row Drag Drop. By default, Tree Grid’s data source will be updated after performing Row Drag and Drop. For example, if we drop any child data to another parent, the ParentID of that child will be refreshed to new parent’s ID. You can check the updated data source after row drag and drop with the help of any events like RowSelected event. 
 
Please check the below video demo, 
 
NOTE: In your code snippet, we could see that you have use HasChildMapping property which is meant for Remote Data alone. Please do not use HasChildMapping property for local data.  
 
Kindly get back to us for further assistance. 
 
Regards, 
Padmavathy Kamalanathan           



BB Basil Buwalda February 1, 2021 09:20 PM UTC

Thanks Padmavathy,

The suggestion has unfortunately not solved the problem. I have attached a screen grab that illustrates my problem a bit more clearly. (I have removed the HasChildMapping as suggested.) 

I assign the     [Parameter] public List DataSource { get; set; }  to the Treegrid as a Datasource, however the changes made in the grid does not flow through to the original Datasource List .

Also you will see that the the values sent to the RowDropped event has not changed yet.

I have included another code snippet with more detail which will hopefully allow you to reproduce the scenario.

In summary, I need the Table below the grid to update after I have dropped the child on a new parent.

Thanks for your help so far.

@page "/TreeGrid"

 

@using Syncfusion.Blazor.TreeGrid

@using Syncfusion.Blazor.Grids

 

<h1>TreeGridh1>

 

@if (DataSource == null)

{

    <p>Loading ... please wait.....p>

}

else

{

    <SfTreeGrid @ref="treeGrid" DataSource="@DataSource" TValue="TreeGridItem"

                DataSourceChanged="TreeGridItemUpdated" IdMapping="Id" ParentIdMapping="ParentId"  ExpandStateMapping="IsExpanded" TreeColumnIndex="1"

                AllowFiltering="true" AllowPaging="true" AllowSorting="true" AllowRowDragAndDrop="true"

                Toolbar="@(new List<string>() { "Add", "Edit", "Delete" })" Height="100%">

        <TreeGridEvents TValue="TreeGridItem"

                        RowDropped="TreeGridItemDropped">TreeGridEvents>

        <TreeGridPageSettings PageSize="3">TreeGridPageSettings>

        <TreeGridEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true" Mode="Syncfusion.Blazor.TreeGrid.EditMode.Dialog">TreeGridEditSettings>

        <TreeGridFilterSettings Type="Syncfusion.Blazor.TreeGrid.FilterType.Menu">TreeGridFilterSettings>

        <TreeGridColumns>

            <TreeGridColumn Field="Id" HeaderText="Id" Width="80" IsPrimaryKey="true" Visible="true" TextAlign="Syncfusion.Blazor.Grids.TextAlign.Right">TreeGridColumn>

            <TreeGridColumn Field="Name" HeaderText="Name" Width="240">TreeGridColumn>

            <TreeGridColumn Field="ParentId" HeaderText="Pid" Width="240" Visible="true">TreeGridColumn>

        TreeGridColumns>

    SfTreeGrid>

 

    <table>

        <thead>

        <th>Idth>

        <th>Nameth>

        <th>ParentIdth>

        <th>IsExpandedth>

        thead>

        @foreach (var tgi in DataSource)

        {

            <tr>

                <td>@tgi.Idtd>

                <td>@tgi.Nametd>

                <td>@tgi.ParentIdtd>

                <td>@tgi.IsExpandedtd>

            tr>

        }

    table>

 

}

 

@code {

    [Parameter] public List DataSource { get; set; }

    protected SfTreeGrid treeGrid;

 

    protected override void OnInitialized()

    {

        DataSource = TreeGridItem.GetSampleData();

        base.OnInitialized();

    }

 

    protected void TreeGridItemUpdated(IEnumerable args)

    {

        foreach (var tgi in args)

        {

            Console.WriteLine($"Updated: {tgi.Id} - {tgi.Name} - {tgi.ParentId}");

        }

    }

 

 

    protected void TreeGridItemDropped(RowDragEventArgs args)

    {

        Console.WriteLine($"Dropped onto element at Index: {args.DropIndex}");

        var ptgi = treeGrid.GetCurrentViewRecords().ElementAtOrDefault((int)args.DropIndex);

        Console.WriteLine($"Dropped onto Item with Id {ptgi.Id} - Name: {ptgi.Name} - ParentId: {ptgi.ParentId}");

        foreach (var tgi in args.Data)

        {

            Console.WriteLine($"Dropped item with Id {tgi.Id} - Name: {tgi.Name} - ParentId: {tgi.ParentId}");

        }

    }

 

    public class TreeGridItem

    {

        public int Id { get; set; }

        public string Name { get; set; }

        public int? ParentId { get; set; }

        public bool IsParent { get; set; } = false;

        public bool IsExpanded { get; set; } = false;

        public static List GetSampleData()

        {

            return new List()

            {

                    new TreeGridItem

                    {

                        Id = 1,

                        Name = "Parent",

                        IsParent = true,

                        IsExpanded = true }

                    ,

                    new TreeGridItem

                    {

                        Id = 2,

                        Name = "Child1",

                        ParentId = 1,

                        IsParent = false,

                        IsExpanded = true }

                    ,

                    new TreeGridItem

                    {

                        Id = 3,

                        Name = "Child2",

                        ParentId = 1,

                        IsParent = false,

                        IsExpanded = true }

                    ,

                    new TreeGridItem

                    {

                        Id = 4,

                        Name = "Parent 2",

                        IsParent = false,

                        IsExpanded = true }

 

                };

        }

    }

}


Attachment: Error_example.gif_5f61f8b.zip


PK Padmavathy Kamalanathan Syncfusion Team February 2, 2021 01:11 PM UTC

Hi Basil, 
 
Thanks for the update.  
 
We have checked issue with your modified code. When we perform drag and drop, the parent id of dragged record from dataSource variable does not get updated and it get updated only on performing any other action (like rows selecting or expand/collapse). We are validating the issue and will update you further details on or before 4th February 2021.  
 
In the meantime, kindly let us know whether you also expect to have changed order of records in the dataSource variable after row drag and drop? 
 
Regards, 
Padmavathy Kamalanathan 



PK Padmavathy Kamalanathan Syncfusion Team February 4, 2021 01:38 PM UTC

Hi Basil, 
 
We appreciate your patience. 
 
We have validated your query at our end. We have considered it as a bug and logged report for the same. Thank you for taking time to report this issue "DataSource variable is not getting updated while using two way binding" and helping us improve our product. Fix for this issue will be included in our bi-weekly release which is expected to be rolled out on or before 16th February 2021. 
 
You can track the current status of your request, review the proposed resolution timeline and contact us for any further queries through this link, 
 
Note: To view the above feedback, kindly login into your account. 
 
Kindly get back to us for further assistance. 
 
Regards, 
Padmavathy Kamalanathan 



PK Padmavathy Kamalanathan Syncfusion Team February 24, 2021 01:09 PM UTC

Hi Basil, 
 
We appreciate your patience. 
 
We are glad to announce that fix for the issue "DataSource variable is not getting updated while using two way binding" has been rolled out in our nuget release. We request you to update to our latest version "18.4.0.43". 
 
Regards, 
Padmavathy Kamalanathan 


Marked as answer
Loader.
Up arrow icon