Skip to content

TTMSFNCKanBanboard

TTMSFNCKANBANBOARD2

Hierarchy

1) Each column in the TMS FNC Kanbanboard has the ability to show a header with optional filtering, sorting and expand/collapse functionality. It can display text with HTML formatting capabilities.

2) Sample of enabling expand/collapse in a column.

3) A TMS FNC Kanbanboard item, which has a title and a description (text). Both parts of the item support HTML formatted text as well as expand/collapse functionality. Optionally the item can be marked with an area (red line at the top of the item).

4) Sample of HTML formatting capabilities in the form of an unordered list.

5) Margins and spacing options for configuring the appearance of the columns. Each column has a separate width property, and on kanbanboard level columns can additionally be configured via the ColumnsAppearance property.

Adding Columns

When starting with the kanbanboard component you’ll notice the initialization of 3 columns with a series of items as a preview. This is done to give you, as a developer, an idea on how this component visualizes columns and items, and which features it exposes. The columns and items can be easily removed by clicking on the component, and then clearing the columns in the object inspector, via the columns collection editor.

TTMSFNCKANBANBOARD2

You’ll then start with an empty kanbanboard instance. Adding columns is as easy as removing them. Click on the new button to create an instance of TTMSFNCKanbanBoardColumn. You’ll notice the kanbanboard is updated with a column, which has a header by default.

TTMSFNCKANBANBOARD3

The “Header 0” value is ofcourse preset by the component, and this can be changed by setting the HeaderText property. Let’s change this to TODO. Additionally, we would also like to change the header appearance, so the header fill and stroke properties can be used for this purpose. After changing these properties, you can expect to see something similar to the screenshot below. (Note that the kanbanboard has a default ColumnAppearance that is applied to all columns. For a specific column appearance, UseDefaultAppearance property needs to be set to False).

TTMSFNCKANBANBOARD4

TTMSFNCKANBANBOARD5

When the above settings need to be configured programmatically, below is a code snippet that demonstrates this.

var
 c: TTMSFNCKanbanBoardColumn;
begin
 TMSFNCKanbanBoard1.BeginUpdate;
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.UseDefaultAppearance := False;
 c.HeaderFill.Color := gcLightgray;
 c.HeaderFill.ColorTo := gcSilver;
 c.HeaderFill.Kind := gfkGradient;
 c.HeaderFont.Color := gcWhite;
 c.HeaderFont.Size := 16;
 c.HeaderFont.Style := [TFontStyle.fsBold];
 c.HeaderText := 'TODO';
 TMSFNCKanbanBoard1.EndUpdate;
end;

Before we add items to our column, we want to add 2 additional columns. These columns will help us in the next chapters, adding and moving items. Add 2 new colums, “IN PROGRESS” and “DONE”, in the same way as the “TODO” column. After adding these 2 columns, we can proceed to add the items.

Adding Items

Each column has an items collection that can be used to add kanbanboard items. Each item represents a task or todo item depending on the way the kanbanboard is configured and for which purpose it is used.

Continuing from our previous sample, we want to add a new TODO item. Adding a new item can be done both at designtime or programmatically (runtime). To add a new item at designtime, select the column in columns collection editor via the object inspector. Click on the items property, which will open the items collection editor. Clicking on the new button will add a new instance of TTMSFNCKanbanBoardItem to the list. You’ll also notice that an item has visually been added to the column. Configuring this item is similar to configuring the column. You can set properties on item level that will change the title and description (text), and you can also change the appearance of the item.

The item also has a UseDefaultAppearance property that is used to override the default appearance coming from the ItemsAppearance property at kanbanboard level. Below is a sample that Demonstrates adding an item both at designtime and at runtime.

TTMSFNCKANBANBOARD6

TTMSFNCKANBANBOARD7

var
 c: TTMSFNCKanbanBoardColumn;
 it: TTMSFNCKanbanBoardItem;
begin
 TMSFNCKanbanBoard1.BeginUpdate;
 c := TMSFNCKanbanBoard1.Columns[0];
  it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Description, Notes';
 TMSFNCKanbanBoard1.EndUpdate;
end;

After adding columns and items, you’ll end up with a Kanban board similar to the one shown in the screenshot below.

TTMSFNCKANBANBOARD8

The full code is

var
 c: TTMSFNCKanbanBoardColumn;
 it: TTMSFNCKanbanBoardItem;
begin
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Color := gcLightgray;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.ColorTo := gcSilver;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Kind := gfkGradient;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Color := gcWhite;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Size := 16;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Style :=
[TFontStyle.fsBold];
 TMSFNCKanbanBoard1.BeginUpdate;
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'TODO';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Description, Notes';
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'IN PROGRESS';
 c := TMSFNCKanbanBoard1.Columns.Add;
c.HeaderText := 'DONE';
 TMSFNCKanbanBoard1.EndUpdate;
end;

Moving Items

Items can be moved between columns, either programmatically or by interaction. The Kanbanboard Interaction property has a DragDropMode property that can be used to move items between columns. You can select kbdmNone, kbdmMove or kbdmCopy. The kbdmCopy setting will do the same as the kbdmMove, but leave a copy of the selected item in the original column. This way, the item can be duplicated.

To start a moving operation, click or tap on the item that needs to be moved. Click/tap again and hold the mouse/finger down on the item. This way, the item can be moved between columns. Now release the item at the new column of choice. When an item is already added to the list, and the dragged item is released on an already existing item, the item will be inserted at that position. When releasing the item inside the column at the end, the item will be added at the end of the column.

For demonstrating the move operation, we add a new item first:

 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'TODO';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Description, Notes';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Move Item';

TTMSFNCKANBANBOARD9

Release the left mouse button / finger in the “IN PROGRESS” column, to move the item to the new column. If we would have selected kbdmCopy instead of kbdmMove, the item will be duplicated, and there would be an item in both the “TODO” and “IN PROGRESS” column.

Of course this can also be done programmatically. To move an item to a specific column, use the MoveItem method at TTMSFNCKanbanBoardItem level.

procedure TForm1.Button1Click(Sender: TObject);
var
 it: TTMSFNCKanbanBoardItem;
begin
 it := TMSFNCKanbanBoard1.SelectedItem;
 if Assigned(it) then
 it.MoveItem(TMSFNCKanbanBoard1.Columns[1]).SelectItem;
end;
The above code will retrieve the selected item, move it to the new column and the select the new item.

TTMSFNCKANBANBOARD10

procedure TForm1.Button1Click(Sender: TObject);
var
 it: TTMSFNCKanbanBoardItem;
begin
 it := TMSFNCKanbanBoard1.SelectedItem;
 if Assigned(it) then
 it.MoveItem(TMSFNCKanbanBoard1.Columns[1]).SelectItem;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
 c: TTMSFNCKanbanBoardColumn;
 it: TTMSFNCKanbanBoardItem;
begin
TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Color := gcLightgray;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.ColorTo := gcSilver;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Kind := gfkGradient;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Color := gcWhite;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Size := 16;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Style :=
[TFontStyle.fsBold];
 TMSFNCKanbanBoard1.BeginUpdate;
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'TODO';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Description, Notes';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Move Item';
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'IN PROGRESS';
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'DONE';
 TMSFNCKanbanBoard1.EndUpdate;
end;

Moving items via interaction can be controlled with events. Sometimes, there is a certain requirement necessary to restrict items from begin moved or copied to a specific column. The OnBeforeDropItem and OnAfterDropItem events can be used to control this requirement.

Expand / Collapse Columns

Each column has the ability to expand and collapse. By default the column is expanded. The Width property, that can be configured at TTMSFNCKanbanBoardColumn level, is the expanded width. You can configure a CollapsedWidth as well which is the width that is used when a column is collapsed. To enable column collapsing, set the Expandable property to true. This way, an additional button is shown in the top-right corner of the header.

TTMSFNCKANBANBOARD11

Clicking on the button will collapse the column, hiding the title and description of the item in a smaller collapsed state. This allows for an easier overview of the other columns, in case the kanbanboard has many columns that exceed the width of the visible area.

TTMSFNCKANBANBOARD12

The column can also be collapsed / expanded at runtime, with the Expanded property at column level. Below is a sample that initializes the first column as collapsed.

TTMSFNCKANBANBOARD13

var
 c: TTMSFNCKanbanBoardColumn;
 it: TTMSFNCKanbanBoardItem;
begin
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Color := gcLightgray;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.ColorTo := gcSilver;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Kind := gfkGradient;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Color := gcWhite;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Size := 16;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Style :=
[TFontStyle.fsBold];
 TMSFNCKanbanBoard1.BeginUpdate;
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'TODO';
 c.Expandable := True;
 c.Expanded := False;
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Description, Notes';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Move Item';
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'IN PROGRESS';
 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'DONE';
 TMSFNCKanbanBoard1.EndUpdate;
end;

Expand / Collapse Items

In the same way as a column is collapsible / expandable, an item can be configured to support this kind of interaction as well. When accessing an item, either at designtime or at runtime. The Expandable property and Expanded property works the same way as the properties at column. The only difference is that the item is collapsed in height instead of in width and that the minimum size if fixed.

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Expand / Collapse Item';
 it.Expandable := True;

TTMSFNCKANBANBOARD14

When clicking the button, the item will shrink in height and only show the title area.

TTMSFNCKANBANBOARD15

Marking an item

An item can be marked, which, by default, shows a colored line at the mark position that can be configured via the MarkType and MarkColor property. The MarkType is a set, so that means that multiple values can be added. This way, you can add multiple colored mark lines. Each line can be colored separately. Additionally, a MarkSize property is available to set the size of the lines.

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Marked Item';
 it.MarkType := [kbmtLeft];

TTMSFNCKANBANBOARD16

Changing the MarkType property to add more mark areas for drawing is shown in the following sample:

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Marked Item';
 it.MarkType := [kbmtLeft, kbmtTop];

TTMSFNCKANBANBOARD17

Additionally, a custom mark can be applied. To do this, the OnItemCustomDrawMark event overrides the default drawing for each mark type. Below is a sample that increase the MarkSize to provide more space for drawing, and adds a bitmapcontainer for drawing a bitmap inside the left mark area. This way, multiple mark areas can be combined drawing either the default appearance or drawing custom graphics.

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Marked Item';
 it.MarkType := [kbmtLeft, kbmtTop];
 it.MarkSizeLeft := 32;
procedure TForm1.TMSFNCKanbanBoard1ItemCustomDrawMark(Sender: TObject;
 AGraphics: TTMSFNCGraphics; ARect: TRectF;
 AMarkType: TTMSFNCKanbanBoardMarkType; AColumn: TTMSFNCKanbanBoardColumn;
 AItem: TTMSFNCKanbanBoardItem);
begin
 case AMarkType of
 kbmtLeft:
 begin
 AGraphics.BitmapContainer := TMSFNCBitmapContainer1;
 AGraphics.DrawBitmapWithName(ConvertToRect(ARect),
TMSFNCBitmapContainer1.BitmapNames[0]);
 end;
 else
 AGraphics.DrawRectangle(ARect, gcrmNone);
 end;
end;

TTMSFNCKANBANBOARD18

Sorting

Sorting is supported for each column in the kanbanboard. By default sorting is not enabled, but this can easily be enabled by using the Sorting property at column level. Setting the sorting property to gsmNormal or gsmNormalCaseSensitive. Let’s enable this on our first column:

 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'TODO';
 c.Sorting := kbsNormal;
Clicking on the header of the column will start a sorting operation. By default the first sorting
operation is descending. Programmatically this can be done with the following code:
 c.Items.Sort(False, kbismAscending);

TTMSFNCKANBANBOARD19

Filtering

Filtering can be applied to each column separately. To enable filtering via interaction, you can set the ShowFilterButton property to true. Let’s apply this on our second column and add another item:

 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'IN PROGRESS';
 c.ShowFilterButton := True;
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Filtering';
 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Searching';

TTMSFNCKANBANBOARD20

Clicking or tapping on this button will show a filter edit box that can be used to filter items in the list. The filter is applied only to the Text property, the Title property is ignored.

TTMSFNCKANBANBOARD21

Filtering can also be applied programmatically, without user interaction.

 f := c.Filter.Add;
 f.Condition := 'Fil*';
 c.ApplyFilter;
The above filter operation will programmatically hide the items that don’t match the filter condition. The filter also has options to filter with or without case sensitivity.

Editing

An item description / text area can be edited. This is done via a memo inplace editor. To enable editing set the property Editing to true at kanbanboard interaction level.

 TMSFNCKanbanBoard1.Interaction.Editing := True;

TTMSFNCKANBANBOARD22

To start editing, click on an item and press either the F2 or Enter key or click/tap on the selected item. This immediately starts inplace editing. Pressing Escape will cancel editing and to accept changes, press F2 or Enter key again, or tap outside the item. After a succesful editing operation, the OnUpdateItemText event is called.

Sample code

The sample code accompanying the above chapters is shown below.

unit Unit10;

interface

uses
 System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants,
 FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
 FMX.TMSFNCTypes, FMX.TMSFNCUtils, FMX.TMSFNCGraphics,
FMX.TMSFNCGraphicsTypes,
 FMX.TMSFNCCustomControl, FMX.TMSFNCCustomScrollControl,
FMX.TMSFNCKanbanBoard,
 FMX.Controls.Presentation, FMX.StdCtrls, FMX.TMSFNCCustomComponent,
 FMX.TMSFNCBitmapContainer, FMX.TMSFNCKanbanBoardDatabaseAdapter;

type
 TForm1 = class(TForm)
 TMSFNCKanbanBoard1: TTMSFNCKanbanBoard;
 Button1: TButton;
 TMSFNCBitmapContainer1: TTMSFNCBitmapContainer;
 TMSFNCKanbanBoardDatabaseAdapter1: TTMSFNCKanbanBoardDatabaseAdapter;
 procedure FormCreate(Sender: TObject);
 procedure Button1Click(Sender: TObject);
 procedure TMSFNCKanbanBoard1ItemCustomDrawMark(Sender: TObject;
 AGraphics: TTMSFNCGraphics; ARect: TRectF;
 AMarkType: TTMSFNCKanbanBoardMarkType; AColumn:
TTMSFNCKanbanBoardColumn;
 AItem: TTMSFNCKanbanBoardItem);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
var
 Form10: TForm1;
implementation
{$R *.fmx}
uses
 FMX.TMSFNCTableView;
procedure TForm1.Button1Click(Sender: TObject);
var
 it: TTMSFNCKanbanBoardItem;
begin
 it := TMSFNCKanbanBoard1.SelectedItem;
 if Assigned(it) then
 it.MoveItem(TMSFNCKanbanBoard1.Columns[1]).SelectItem;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
 c: TTMSFNCKanbanBoardColumn;
 it: TTMSFNCKanbanBoardItem;
 f: TTMSFNCTableViewFilterData;
begin
 TMSFNCKanbanBoard1.BeginUpdate;
 TMSFNCKanbanBoard1.Columns.Clear;

 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Color := gcLightgray;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.ColorTo := gcSilver;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFill.Kind := gfkGradient;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Color := gcWhite;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Size := 16;
 TMSFNCKanbanBoard1.ColumnsAppearance.HeaderFont.Style :=
[TFontStyle.fsBold];

 c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'TODO';
 c.Sorting := kbsNormal;
 c.Items.Sort(False, kbismAscending);

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Description, Notes';

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Move Item';

c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'IN PROGRESS';
 c.ShowFilterButton := True;

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Expand / Collapse Item';
 it.Expandable := True;

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Filtering';

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Searching';

 f := c.Filter.Add;
 f.Condition := 'F*';

 c.ApplyFilter;
c := TMSFNCKanbanBoard1.Columns.Add;
 c.HeaderText := 'DONE';

 it := c.Items.Add;
 it.Title := 'New Item';
 it.Text := 'Marked Item';
 it.MarkType := [kbmtLeft, kbmtTop];
 it.MarkSizeLeft := 32;

 TMSFNCKanbanBoard1.Interaction.Editing := True;

 TMSFNCKanbanBoard1.EndUpdate;
end;

procedure TForm1.TMSFNCKanbanBoard1ItemCustomDrawMark(Sender: TObject;
 AGraphics: TTMSFNCGraphics; ARect: TRectF;
 AMarkType: TTMSFNCKanbanBoardMarkType; AColumn: TTMSFNCKanbanBoardColumn;
 AItem: TTMSFNCKanbanBoardItem);
begin
 case AMarkType of
 kbmtLeft:
 begin
 AGraphics.BitmapContainer := TMSFNCBitmapContainer1;
 AGraphics.DrawBitmapWithName(ConvertToRect(ARect),
TMSFNCBitmapContainer1.BitmapNames[0]);
 end;
 else
 AGraphics.DrawRectangle(ARect, gcrmNone);
 end;
end;

end.

Database Adapter

The kanbanboard supports loading and manipulating items from a dataset. The TTMSFNCKanbanBoardDatabaseAdapter component can be used for this purpose. Data-enabling is easy and only requires the following 3 steps:

1) Prepare your dataset to match fields / data according to the requirements of the kanbanboard database adapter. The field requirements are:

Column: Integer DBKey: string Text: string Title: String

2) Attach the DataSource to the kanbanboard database adapter. 3) Attach the kanbanboard database adapter to the Adapter property of the kanbanboard. 4) Set Active to True.

Additionally, the kanbanboard database adapter supports mapping other fields to the item as well. This is done via the OnFieldsToItem and OnItemToFields. These 2 events also have the column equivalent in case specific settings need to be done at column level.

Below is a sample with a TClientDataSet that has been filled programmatically with a few items, hooked up to a kanbanboard database adapter and connected to a kanbanboard.

unit UDemo;

interface

uses
 Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
 Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VCL.TMSFNCTypes, VCL.TMSFNCUtils,
 VCL.TMSFNCGraphics, VCL.TMSFNCGraphicsTypes, VCL.TMSFNCCustomComponent,
 VCL.TMSFNCKanbanBoard, VCL.TMSFNCKanbanBoardDatabaseAdapter,
 VCL.TMSFNCCustomControl, VCL.TMSFNCCustomScrollControl, Data.DB,
 Datasnap.DBClient, Vcl.StdCtrls;
type
 TForm1 = class(TForm)
 TMSFNCKanbanBoard1: TTMSFNCKanbanBoard;
 TMSFNCKanbanBoardDatabaseAdapter1: TTMSFNCKanbanBoardDatabaseAdapter;
 ClientDataSet1: TClientDataSet;
 DataSource1: TDataSource;
 Button1: TButton;
 procedure FormCreate(Sender: TObject);
 procedure TMSFNCKanbanBoardDatabaseAdapter1FieldsToItem(Sender:
TObject;
 AFields: TFields; AItem: TTMSFNCKanbanBoardItem);
 procedure Button1Click(Sender: TObject);
 procedure TMSFNCKanbanBoardDatabaseAdapter1ColumnToFields(Sender:
TObject;
 AColumn: Integer; AFields: TFields; AColumnField: TField);
 procedure TMSFNCKanbanBoardDatabaseAdapter1FieldsToColumn(Sender:
TObject;
 AFields: TFields; AColumnField: TField; var AColumn: Integer;
 var AAccept: Boolean);
 private
 { Private declarations }
 procedure DoTreeViewMouseDown(Sender: TObject; Button:
TTMSFNCMouseButton; Shift: TShiftState; X, Y: Integer);
 public
 { Public declarations }
 end;
var
 Form34: TForm1;
implementation
{$R *.dfm}
uses
 VCL.TMSFNCTreeViewData;
type
 TTMSFNCKanbanBoardOpen = class(TTMSFNCKanbanBoard);
procedure TForm1.Button1Click(Sender: TObject);
begin
 TMSFNCKanbanBoardDatabaseAdapter1.Active := not
TMSFNCKanbanBoardDatabaseAdapter1.Active;
end;

procedure TForm1.DoTreeViewMouseDown(Sender: TObject;
 Button: TTMSFNCMouseButton; Shift: TShiftState; X, Y: Integer);
var
 it: TTMSFNCTreeViewVirtualNode;
begin
 it := (Sender as TTMSFNCKanbanBoardTreeViewTableView).XYToNode(X, Y);
 if Assigned(it) then
 (Sender as TTMSFNCKanbanBoardTreeViewTableView).SelectVirtualNode(it);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
 I: Integer;
begin
 DataSource1.DataSet := ClientDataSet1;

 ClientDataSet1.FieldDefs.Add('Id', ftString, 255);
 ClientDataSet1.FieldDefs.Add('Column', ftString, 10);
 ClientDataSet1.FieldDefs.Add('Title', ftString, 10);
 ClientDataSet1.FieldDefs.Add('Text', ftString, 255);
 ClientDataSet1.FieldDefs.Add('Color', ftLongWord);
 ClientDataSet1.CreateDataSet;

 TMSFNCKanbanBoard1.Adapter := TMSFNCKanbanBoardDatabaseAdapter1;
 TMSFNCKanbanBoardDatabaseAdapter1.Item.AutoIncrementDBKey := False;
 TMSFNCKanbanBoardDatabaseAdapter1.Item.DataSource := DataSource1;
 TMSFNCKanbanBoardDatabaseAdapter1.Item.DBKey := 'Id';
 TMSFNCKanbanBoardDatabaseAdapter1.Item.Title := 'Title';
 TMSFNCKanbanBoardDatabaseAdapter1.Item.Text := 'Text';
 TMSFNCKanbanBoardDatabaseAdapter1.Item.Column := 'Column';

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -4;
 ClientDataSet1.FieldByName('Title').AsString := 'Miami';
 ClientDataSet1.FieldByName('Text').AsString := 'Dialy shoot at the beach';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcOrange;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'New York';
 ClientDataSet1.FieldByName('Text').AsString := 'Shoe model';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcDarkgray;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'New York';
 ClientDataSet1.FieldByName('Text').AsString := 'Shoe model';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcDarkgray;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'Barcelona';
 ClientDataSet1.FieldByName('Text').AsString := 'Audition for photoshoot';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcDarkgray;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -4;
 ClientDataSet1.FieldByName('Title').AsString := 'TV Ad';
 ClientDataSet1.FieldByName('Text').AsString := 'Advertisement for toothpaste';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcGhostwhite;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'Barcelona';
 ClientDataSet1.FieldByName('Text').AsString := 'Meet with Daniel Harris for audition';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcGhostwhite;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'Clothes';
 ClientDataSet1.FieldByName('Text').AsString := 'New clothes line presentation in Milan';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcSeagreen;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'Photoshoot';
 ClientDataSet1.FieldByName('Text').AsString := 'Photoshoot for bikini magazine';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcSkyblue;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -3;
 ClientDataSet1.FieldByName('Title').AsString := 'Catwalk';
 ClientDataSet1.FieldByName('Text').AsString := 'Catwalk in Paris';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcPlum;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -2;
 ClientDataSet1.FieldByName('Title').AsString := 'TV Ad';
 ClientDataSet1.FieldByName('Text').AsString := 'Dinner with friends at
the seafood restaurant while shooting a new advertisement';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcLightpink;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;

ClientDataSet1.FieldByName('Column').AsInteger := -2;
 ClientDataSet1.FieldByName('Title').AsString := 'Catwalk';
 ClientDataSet1.FieldByName('Text').AsString := 'Catwalk in Barcelona';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcLightpink;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -2;
 ClientDataSet1.FieldByName('Title').AsString := 'Test shoot';
 ClientDataSet1.FieldByName('Text').AsString := 'Test shoot at the market in Phuket';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcDarkkhaki;

 ClientDataSet1.Insert;
 ClientDataSet1.FieldByName('Id').AsString := TGuid.NewGuid.ToString;
 ClientDataSet1.FieldByName('Column').AsInteger := -2;
 ClientDataSet1.FieldByName('Title').AsString := 'Test shoot 2';
 ClientDataSet1.FieldByName('Text').AsString := 'Second Test shoot at the
market in Phuket';
 ClientDataSet1.FieldByName('Color').AsLongWord := gcDarkkhaki;

 ClientDataSet1.Post;

 TMSFNCKanbanBoard1.Interaction.Editing := True;

 for I := 0 to TMSFNCKanbanBoard1.Columns.Count - 1 do
 TMSFNCKanbanBoard1.Columns[I].TableView.TreeView.OnMouseDown :=
DoTreeViewMouseDown;
end;

procedure TForm1.TMSFNCKanbanBoardDatabaseAdapter1ColumnToFields(
 Sender: TObject; AColumn: Integer; AFields: TFields; AColumnField:
TField);
begin
 AColumnField.AsInteger := AColumn - 4;
end;

procedure TForm1.TMSFNCKanbanBoardDatabaseAdapter1FieldsToColumn(
 Sender: TObject; AFields: TFields; AColumnField: TField; var AColumn:
Integer;
 var AAccept: Boolean);
begin
 AColumn := AColumn + 4;
end;

procedure TForm1.TMSFNCKanbanBoardDatabaseAdapter1FieldsToItem(Sender:
TObject;
 AFields: TFields; AItem: TTMSFNCKanbanBoardItem);
var
 c: TTMSFNCGraphicsColor;
begin
 c := AFields.FieldByName('Color').AsLongWord;
 if c <> gcNull then
 begin
 AItem.Color := c;
 AItem.UseDefaultAppearance := False;
else
 AItem.UseDefaultAppearance := True;
end;
end.

Important methods, properties and events

Properties

Property name Description
Columns[Index] The collection of columns shown in the kanbanboard.
ColumnsAppearance The overall columns appearance, applied when UseDefaultAppearance of the column collection item is set to "True".
GlobalFont Use to change all of the components fonts in one time.
Interaction Various interaction properties for controlling the kanbanboard behaviour.
ItemsAppearance The appearance of the items in applied to all items with UseDefaultAppearance set to True.

Methods

Method name Description
Columns[Index] The collection of columns shown in the kanbanboard.
FindItemWithDBKey(ADBKey: String): TTMSFNCKanbanBoardItem; Returns an item with a specific DBKey. Used in combination with an active database adapter connection.
SelectedItem: TTMSFNCKanbanBoardItem; Return the selected item.
SelectItem(AItem: TTMSFNCKanbanBoardItem); Selects an item.
XYToColumn(X, Y: Single): TTMSFNCKanbanBoardColumn; Returns the column at a specific X and Y coordinate.

Events

Event name Description
OnAfterApplyFilter Event triggered after the filter is applied via interaction.
OnAfterDrawItem Event triggered after an item is drawn.
OnAfterDrawItemText Event triggered after the text / description of an item is drawn.
OnAfterDrawItemTitle Event triggered after the title of an item is drawn.
OnAfterDropItem Event triggered after an item is moved, reordered or copied.
OnBeforeApplyFilter Event triggered before a filter is applied via interaction.
OnBeforeDrawItem Event triggered before an item is drawn.
OnBeforeDrawItemText Event triggered before the text / description of an item is drawn.
OnBeforeDrawItemTitle Event triggered before the title of an item is drawn.
OnBeforeDropItem Event triggered before an item is moved, reordered or copied.
OnColumnCollapse Event triggered when a column is collapsed.
OnColumnExpand Event triggered when a column is expanded.
OnCustomizeColumn Event triggered when a column is added to the kanban board. This event allows further customization to the internal tableview representing a column.
OnDoneButtonClicked Event triggered when the done button is clicked.
OnItemCollapse Event triggered when an item is collapsed.
OnItemCompare Event triggered when a column is sorted to allow custom sorting.
OnItemCustomDrawMark Even triggered when an item mark is drawn. This event allows customization of the mark area.
OnItemExpand Event triggered when an item is expanded.
OnSelectItem Event triggered when an item is selected.
OnUpdateItemText Event triggered when an item text / description is updated.