Swimlane in WinUI Kanban Board
18 Nov 201824 minutes to read
Swimlanes are horizontal categorizations of cards that help group and organize work items. They provide greater transparency into the workflow and allow you to categorize work by projects, teams, users, or any other criteria.
By default, swimlanes are categorized based on the Assignee values in the KanbanModel class. You can also define a category by mapping the SwimlaneKey to the appropriate property name in the KanbanModel class.
The following example code demonstrates how to group the underlying data collection using the SwimlaneKey property.
<kanban:SfKanban x:Name="kanban"
SwimlaneKey="IndicatorColorKey"
ItemsSource="{Binding TaskDetails}">
<kanban:SfKanban.DataContext>
<local:ViewModel/>
</kanban:SfKanban.DataContext>
</kanban:SfKanban>this.kanban.SwimlaneKey = "IndicatorColorKey";
this.kanban.ItemsSource = new ViewModel().TaskDetails;public class ViewModel
{
#region Properties
/// <summary>
/// Gets or sets the collection of <see cref="KanbanModel"/> objects representing tasks in various stages.
/// </summary>
public ObservableCollection<KanbanModel> TaskDetails { get; set; }
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="ViewModel"/> class.
/// </summary>
public ViewModel()
{
this.TaskDetails = this.GetTaskDetails();
}
#endregion
#region Private methods
/// <summary>
/// Method to get the kanban model collections.
/// </summary>
/// <returns>The kanban model collections.</returns>
private ObservableCollection<KanbanModel> GetTaskDetails()
{
var taskDetails = new ObservableCollection<KanbanModel>();
string path = @"ms-appx:///";
KanbanModel taskDetail = new KanbanModel();
taskDetail.Title = "Customer meeting";
taskDetail.Id = "1";
taskDetail.Assignee = "Janet Leverling";
taskDetail.Description = "Arrange a web meeting with the customer to get new requirements.";
taskDetail.Category = "Open";
taskDetail.IndicatorColorKey = "High";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle1.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Edge browser issues";
taskDetail.Id = "1";
taskDetail.Assignee = "Janet Leverling";
taskDetail.Description = "Fix the issues reported in the IE browser.";
taskDetail.Category = "In Progress";
taskDetail.IndicatorColorKey = "Normal";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle1.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Login validation";
taskDetail.Id = "1";
taskDetail.Assignee = "Janet Leverling";
taskDetail.Description = "Login page validation.";
taskDetail.Category = "Done";
taskDetail.IndicatorColorKey = "Low";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle1.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Application performance";
taskDetail.Id = "2";
taskDetail.Assignee = "Andrew Fuller";
taskDetail.Description = "Improve application performance.";
taskDetail.Category = "Open";
taskDetail.IndicatorColorKey = "Normal";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle5.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Analysis";
taskDetail.Id = "2";
taskDetail.Assignee = "Andrew Fuller";
taskDetail.Description = "Analyze SQL server 2008 connection.";
taskDetail.Category = "In Progress";
taskDetail.IndicatorColorKey = "High";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle5.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Data binding issues";
taskDetail.Id = "2";
taskDetail.Assignee = "Andrew Fuller";
taskDetail.Description = "Fix the issues reported in data binding.";
taskDetail.Category = "Done";
taskDetail.IndicatorColorKey = "Normal";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle5.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Editing";
taskDetail.Id = "3";
taskDetail.Assignee = "Laura Callahan";
taskDetail.Description = "Enhance editing functionality.";
taskDetail.Category = "Open";
taskDetail.IndicatorColorKey = "Low";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle4.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Responsive support";
taskDetail.Id = "3";
taskDetail.Assignee = "Laura Callahan";
taskDetail.Description = "Add responsive support to application.";
taskDetail.Category = "In Progress";
taskDetail.IndicatorColorKey = "Low";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle4.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Filtering feature";
taskDetail.Id = "3";
taskDetail.Assignee = "Laura Callahan";
taskDetail.Description = "Check filtering validation.";
taskDetail.Category = "Done";
taskDetail.IndicatorColorKey = "High";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle4.png"))
};
taskDetails.Add(taskDetail);
return taskDetails;
}
#endregion
}
Customize swimlane header
You can customize the appearance of swimlane headers using the SwimlaneHeaderTemplate property. This enables you to create a unique design for the header displayed at the beginning of each swimlane group.
The following example demonstrates how to customize a swimlane header.
<kanban:SfKanban x:Name="kanban"
SwimlaneKey="IndicatorColorKey"
ItemsSource="{Binding TaskDetails}">
<kanban:SfKanban.SwimlaneHeaderTemplate>
<DataTemplate x:Name="swimlaneHeaderTemplate">
<Grid>
<Border BorderBrush="Black"
CornerRadius="5,5,5,5"
Width="150"
Margin="10,2,10,0"
HorizontalAlignment="Left">
<StackPanel Background="LightGray"
x:Name="SwimlaneHeaderPanel"
Orientation="Horizontal">
<Grid x:Name="CollapsedIcon"
Background="Transparent"
Height="30"
Width="30">
<Path x:Name="ExpandedPath"
IsHitTestVisible="False"
Data="M30.587915,0L31.995998,1.4199842 15.949964,17.351 0,1.4979873 1.4099131,0.078979151 15.949964,14.53102z"
Stretch="Uniform"
Fill="#FF000000"
Width="14"
Height="14"
Margin="0,0,0,0"
RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1"
ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
<Path x:Name="CollapsedPath"
Visibility="Collapsed"
IsHitTestVisible="False"
Data="M1.4200482,0L17.351001,16.046996 1.4980513,31.996001 0.078979631,30.585997 14.531046,16.046019 0,1.4089964z"
Stretch="Uniform"
Fill="#FF000000"
Width="14"
Height="14"
Margin="0,0,0,0"
RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="0" />
<ScaleTransform ScaleX="1"
ScaleY="1" />
</TransformGroup.Children>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Grid>
<TextBlock FontWeight="Medium"
IsHitTestVisible="False"
FontSize="15"
FontStretch="Expanded"
TextWrapping="NoWrap"
VerticalAlignment="Center"
Text="{Binding Title}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</kanban:SfKanban.SwimlaneHeaderTemplate>
<kanban:SfKanban.DataContext>
<local:ViewModel />
</kanban:SfKanban.DataContext>
</kanban:SfKanban>this.kanban.SwimlaneKey = "IndicatorColorKey";
this.kanban.ItemsSource = new ViewModel().TaskDetails;public class ViewModel
{
#region Properties
/// <summary>
/// Gets or sets the collection of <see cref="KanbanModel"/> objects representing tasks in various stages.
/// </summary>
public ObservableCollection<KanbanModel> TaskDetails { get; set; }
#endregion
#region Constructor
/// <summary>
/// Initializes a new instance of the <see cref="ViewModel"/> class.
/// </summary>
public ViewModel()
{
this.TaskDetails = this.GetTaskDetails();
}
#endregion
#region Private methods
/// <summary>
/// Method to get the kanban model collections.
/// </summary>
/// <returns>The kanban model collections.</returns>
private ObservableCollection<KanbanModel> GetTaskDetails()
{
var taskDetails = new ObservableCollection<KanbanModel>();
string path = @"ms-appx:///";
KanbanModel taskDetail = new KanbanModel();
taskDetail.Title = "Customer meeting";
taskDetail.Id = "1";
taskDetail.Assignee = "Janet Leverling";
taskDetail.Description = "Arrange a web meeting with the customer to get new requirements.";
taskDetail.Category = "Open";
taskDetail.IndicatorColorKey = "High";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle1.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Edge browser issues";
taskDetail.Id = "1";
taskDetail.Assignee = "Janet Leverling";
taskDetail.Description = "Fix the issues reported in the IE browser.";
taskDetail.Category = "In Progress";
taskDetail.IndicatorColorKey = "Normal";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle1.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Login validation";
taskDetail.Id = "1";
taskDetail.Assignee = "Janet Leverling";
taskDetail.Description = "Login page validation.";
taskDetail.Category = "Done";
taskDetail.IndicatorColorKey = "Low";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle1.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Application performance";
taskDetail.Id = "2";
taskDetail.Assignee = "Andrew Fuller";
taskDetail.Description = "Improve application performance.";
taskDetail.Category = "Open";
taskDetail.IndicatorColorKey = "Normal";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle5.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Analysis";
taskDetail.Id = "2";
taskDetail.Assignee = "Andrew Fuller";
taskDetail.Description = "Analyze SQL server 2008 connection.";
taskDetail.Category = "In Progress";
taskDetail.IndicatorColorKey = "High";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle5.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Data binding issues";
taskDetail.Id = "2";
taskDetail.Assignee = "Andrew Fuller";
taskDetail.Description = "Fix the issues reported in data binding.";
taskDetail.Category = "Done";
taskDetail.IndicatorColorKey = "Normal";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle5.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Editing";
taskDetail.Id = "3";
taskDetail.Assignee = "Laura Callahan";
taskDetail.Description = "Enhance editing functionality.";
taskDetail.Category = "Open";
taskDetail.IndicatorColorKey = "Low";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle4.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Responsive support";
taskDetail.Id = "3";
taskDetail.Assignee = "Laura Callahan";
taskDetail.Description = "Add responsive support to application.";
taskDetail.Category = "In Progress";
taskDetail.IndicatorColorKey = "Low";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle4.png"))
};
taskDetails.Add(taskDetail);
taskDetail = new KanbanModel();
taskDetail.Title = "Filtering feature";
taskDetail.Id = "3";
taskDetail.Assignee = "Laura Callahan";
taskDetail.Description = "Check filtering validation.";
taskDetail.Category = "Done";
taskDetail.IndicatorColorKey = "High";
taskDetail.Image = new Image
{
Source = new BitmapImage(new Uri(path + "Assets/Kanban/People_Circle4.png"))
};
taskDetails.Add(taskDetail);
return taskDetails;
}
#endregion
}NOTE
The
DataContextfor the SwimlaneHeaderTemplate property in SfKanban is the first KanbanModel in the swimlane group, so you can bind to any KanbanModel property (e.g.,Title,Assignee, or the property mapped via SwimlaneKey).
