Kanban board complex data binding

Hi, is it possible to bind complex data in a Kanban card? If yes, how?

I have tried to use the dot (.) operator in the ContentField like in a DataGrid column, but I'm getting a NullReferenceException with this.

My board looks like this:
<SfKanban TValue="Account" KeyField="@nameof(Account.State)" AllowDragAndDrop="true" DataSource=@accounts>
<KanbanColumns>
<KanbanColumn HeaderText="Active" KeyField="@(new List<string>() { nameof(State.Active) })" />
<KanbanColumn HeaderText="Disabled" KeyField="@(new List<string>() { nameof(State.Disabled) })" />
<KanbanColumn HeaderText="Deleted" KeyField="@(new List<string>() { nameof(State.Deleted) })" />
</KanbanColumns>
<KanbanCardSettings HeaderField="@nameof(Account.Title)" ContentField="Data.Description" />
</SfKanban>

Thank you for you support.

Regards
Daniel

EDIT:
I now have managed this using a template. Is there also a way without templates?

6 Replies

DA Daniel May 7, 2021 04:19 PM UTC

EDIT 2: I get the same error when I try to set the swimlane TextField to a complex field. I tried to get around this by using a template but this doesn't seem to work here because I only get a SwimlaneSettingsModel and not my data as context. How can I achieve to use complex data here?


IS Indrajith Srinivasan Syncfusion Team May 10, 2021 12:10 PM UTC

Hi Daniel, 
 
Greetings from Syncfusion support, 
 
We have validated your reported queries. You can bind the complex properties, for the Kanban ContentField and TextField of SwimlaneSettings by binding the complex properties and loading it for the DataSource dynamically with their corresponding complex objects values. We have also prepared a sample, that tries to meet your requirements. 
 
Code blocks: 
 
 
<h3>Kanban board complex data binding for the ContentField</h3> 
 
<SfKanban TValue="changedData" @ref="Kanbanobj" KeyField="@nameof(changedData.Status)" AllowDragAndDrop="true" DataSource=@Tasks > 
    <KanbanEvents TValue="changedData"></KanbanEvents> 
    <KanbanColumns> 
        <KanbanColumn HeaderText="Active" KeyField="@(new List<string>() { nameof(StatusActiveModels.Open) })" /> 
        <KanbanColumn HeaderText="Disabled" KeyField="@(new List<string>() { nameof(StatusActiveModels.Validate) })" /> 
        <KanbanColumn HeaderText="Deleted" KeyField="@(new List<string>() { nameof(StatusActiveModels.Close) })" /> 
</SfKanban> 
 
<h3>Swimlane Kanban board complex data binding for TextField</h3> 
 
<SfKanban TValue="swimlanedData" KeyField="Status" DataSource="@swimlaneTasks"> 
    <KanbanColumns> 
        <KanbanColumn HeaderText="Backlog" KeyField="@(new List<string>() {"Open"})"></KanbanColumn> 
        <KanbanColumn HeaderText="In Progress" KeyField="@(new List<string>() {"InProgress"})"></KanbanColumn> 
        <KanbanColumn HeaderText="Testing" KeyField="@(new List<string>() {"Testing"})"></KanbanColumn> 
        <KanbanColumn HeaderText="Done" KeyField="@(new List<string>() {"Close"})"></KanbanColumn> 
    </KanbanColumns> 
    <KanbanCardSettings HeaderField="Id" ContentField="Summary"></KanbanCardSettings> 
    <KanbanSwimlaneSettings KeyField="Assignee" TextField="@nameof(swimlanedData.AssigneeName)"></KanbanSwimlaneSettings> 
</SfKanban> 
 
@code {  
 
public List<changedData> Tasks = new List<changedData>(); 
    public List<swimlanedData> swimlaneTasks = new List<swimlanedData>(); 
    List<changedData> kanbanData = new List<changedData>(); 
    List<swimlanedData> swimlaneData = new List<swimlanedData>(); 
 
public List<TasksModel> complexTasks = new List<TasksModel>() 
{ 
        new TasksModel { Id = "Task 1", Title = "BLAZ-29001", Status = new StatusModel() { keyfield = "Open" }, Summary = "Analyze the new requirements gathered from the customer.", Assignee = "Nancy Davloio", Type = "Story", Priority = "Low" }, 
        new TasksModel { Id = "Task 2", Title = "BLAZ-29002", Status = new StatusModel() { keyfield = "Validate" }, Summary = "Improve application performance", Assignee = "Andrew Fuller", Type = "Improvement", Priority = "Normal" }, 
        new TasksModel { Id = "Task 3", Title = "BLAZ-29003", Status = new StatusModel() { keyfield = "Open" }, Summary = "Arrange a web meeting with the customer to get new requirements.", Assignee = "Janet Leverling", Type = "Others", Priority = "Critical" }, 
        new TasksModel { Id = "Task 4", Title = "BLAZ-29004", Status = new StatusModel() { keyfield = "Close" }, Summary = "Fix the issues reported in the IE browser.", Assignee = "Janet Leverling", Type = "Bug", Priority = "Release Breaker" }, 
        new TasksModel { Id = "Task 5", Title = "BLAZ-29005", Status = new StatusModel() { keyfield = "Validate" }, Summary = "Fix the issues reported by the customer.", Assignee = "Steven walker", Type = "Bug", Priority = "Low" }, 
        new TasksModel { Id = "Task 6", Title = "BLAZ-29006", Status = new StatusModel() { keyfield = "Validate" }, Summary = "Fix the issues reported in Safari browser.", Assignee = "Nancy Davloio", Type = "Others", Priority = "Low" }, 
        new TasksModel { Id = "Task 7", Title = "BLAZ-29007", Status = new StatusModel() { keyfield = "Close" }, Summary = "Test the application in the IE browser.", Assignee = "Margaret hamilt", Type = "Improvement", Priority = "Low" }, 
        new TasksModel { Id = "Task 8", Title = "BLAZ-29008", Status = new StatusModel() { keyfield = "Validate" }, Summary = "Validate the issues reported by the customer.", Assignee = "Steven walker", Type = "Story", Priority = "Release Breaker" }, 
        new TasksModel { Id = "Task 9", Title = "BLAZ-29009", Status = new StatusModel() { keyfield = "Open" }, Summary = "Show the retrieved data from the server in grid control.", Assignee = "Margaret hamilt", Type = "Bug", Priority = "Release Breaker" }, 
    }; 
 
public List<SwimlaneTasksModel> kanbanswimlaneTasks = new List<SwimlaneTasksModel>() 
{ 
        new SwimlaneTasksModel { Id = "Task 1", Title = "BLAZ-29001", Status = "Open", Summary = "Analyze the new requirements gathered from the customer.", Assignee = "Nancy Davloio", AssigneeName = new SwimlaneAssignee() { name = "Nancy" } }, 
        new SwimlaneTasksModel { Id = "Task 2", Title = "BLAZ-29002", Status = "InProgress", Summary = "Improve application performance", Assignee = "Andrew Fuller", AssigneeName = new SwimlaneAssignee() { name = "Andrew" } }, 
        new SwimlaneTasksModel { Id = "Task 3", Title = "BLAZ-29003", Status = "Open", Summary = "Arrange a web meeting with the customer to get new requirements.", Assignee = "Janet Leverling", AssigneeName = new SwimlaneAssignee() { name = "Janet" } }, 
        new SwimlaneTasksModel { Id = "Task 4", Title = "BLAZ-29004", Status = "InProgress", Summary = "Fix the issues reported in the IE browser.", Assignee = "Janet Leverling", AssigneeName = new SwimlaneAssignee() { name = "Janet" } }, 
        new SwimlaneTasksModel { Id = "Task 5", Title = "BLAZ-29005", Status = "Review", Summary = "Fix the issues reported by the customer.", Assignee = "Steven walker", AssigneeName = new SwimlaneAssignee() { name = "Steven" } }, 
        new SwimlaneTasksModel { Id = "Task 6", Title = "BLAZ-29006", Status = "Review", Summary = "Fix the issues reported in Safari browser.", Assignee = "Nancy Davloio", AssigneeName = new SwimlaneAssignee() { name = "Nancy" }  }, 
        new SwimlaneTasksModel { Id = "Task 7", Title = "BLAZ-29007", Status = "Close", Summary = "Test the application in the IE browser.", Assignee = "Margaret hamilt", AssigneeName = new SwimlaneAssignee() { name = "Margaret" } } 
    }; 
 
protected override void OnInitialized() 
    { 
        for (var b = 0; b < complexTasks.Count; b++) 
        { 
            var data = complexTasks[b]; 
            changedData cardObj = new changedData() 
            { 
                Id = data.Id, 
                Title = data.Title, 
                Status = data.Status.keyfield, 
                Assignee = data.Assignee, 
                Priority = data.Priority, 
                Summary = data.Summary, 
                Type = data.Type, 
            }; 
            kanbanData.Add(cardObj); 
        } 
        this.Tasks = kanbanData; 
        for (var b = 0; b < kanbanswimlaneTasks.Count; b++) 
        { 
            var data = kanbanswimlaneTasks[b]; 
            swimlanedData swimlaneObj = new swimlanedData() 
            { 
                Id = data.Id, 
                Title = data.Title, 
                Status = data.Status, 
                Summary = data.Assignee, 
                Assignee = data.Assignee, 
                AssigneeName = data.AssigneeName.name 
            }; 
            swimlaneData.Add(swimlaneObj); 
        } 
        this.swimlaneTasks = swimlaneData; 
    } 
 
} 
  
 
Please let us know if the solution helps, 
 
Regards, 
Indrajith 



DA Daniel May 10, 2021 04:50 PM UTC

Hi Indrajith,

thank you for the solution you provided, this works fine. 

However, is there an easier approach to this where you don't need to create a new class and copy all elements over? This is a hassle to work with Adaptors this way and also with a very big data source this has the potential to slow down your application since you have to copy every single entity to a new instance.

Regards
Daniel


RK Revanth Krishnan Syncfusion Team May 12, 2021 04:12 AM UTC

Hi Daniel, 
 
 
Good day to you. 
 
 
We have further validated your query and have considered “Provide support for complex data binding in Kanban” as a feature request from our end and logged the report for the same and the fix will be included with any of our upcoming releases. 
    
You can now track the current status of the report, review the proposed resolution timeline, and contact us for any further inquiries through this link: https://www.syncfusion.com/feedback/25247 
 
Regards, 
Revanth 



DA Daniel May 12, 2021 10:53 AM UTC

Okay great, thank you for your support!


IS Indrajith Srinivasan Syncfusion Team May 13, 2021 08:47 AM UTC

Hi Daniel,

Welcome,

We will let you know, once the "Complex data binding" support is provided.

Regards,
Indrajith

Loader.
Up arrow icon