Get started

Get and apply the software library to your project using the NuGet package.

The necessary DlhSoft.* assembly references (based on whether you are using .NET Framework or .NET Core/5+) are automatically added to your application project in Visual Studio®. Reference the appropriate namespace in code with an xmlns attribute for the XAML root element and/or a using clause in code behind:


<Window …
        xmlns:kl = "clr-namespace:KanbanLibrary;assembly=KanbanLibrary">

                                

Add the required control instances as child nodes of appropriate XAML container elements or create component objects in code behind:


<DockPanel>
    …
    <kl:KanbanBoard Name="KanbanBoard" … />
</DockPanel>

                                

Data items

To load and present data items within KanbanBoard component instances initialize their Items collections (with a single setter or Add method calls). KanbanItem class that you should use provides these properties:

  • Content: usually a string specifying an item's name;
  • State: object of type KanbanState, from KanbanBoard.States collection, indicating the column of the item;
  • Group: optional object of type KanbanGroup, from KanbanBoard.Groups collection, identifying the row that should contain the item; by default there is a single group defined, and group headers are not visible; note: KanbanBoard.GroupStates can provide a subset of states available for groups; states can also be collapsed for groups (e.g. a group with Done state would automatically be displayed as collapsed) by having IsCollapsedByDefaultForGroups set as true;
  • ItemSource: the icon of the item;
  • ItemType: of type KanbanItemType, specifying the type that the item has; the types available built-in include: KanbanBoard.TaskItemType, BugItemType, StoryItemType, FeatureItemType, and EpicItemType; the developer, may also define custom KanbanItemType instances as needed;
  • Description: supplemental text describing the item (hidden by default; visibility controlled by KanbanBoard.DescriptionVisibility);
  • Resources: list of objects of type KanbanResource, from KanbanBoard.AvailableResources, referring people or other type of assignments bound to the item;
  • Categories: list of objects of type KanbanCategory, from KanbanBoard.AvailableCategories, that the item is labeled with;
  • ItemDate: typically a due date assigned to the item (hidden by default; visibility controlled by KanbanBoard.ItemDateVisibility);
  • IsReadOnly: indicates whether the item should be considered entirely read only;
  • HandleBrush, Background, Foreground: brushes to use upon drawing the item's bar in the board when the default templates are used;
  • Template, ContentTemplate: can redefine the entire item's bar template or the content part within the bar, if needed, for the individual item;
  • Tag: indicating any object that is to be attached to this item.

Supplementary, KanbanGroup objects also offer these properties:

  • IsExpanded, IsCollapsed: indicate or set whether the group is currently expanded or collapsed;
  • AreNewItemButtonsHidden, AreEditItemButtonsHidden: control whether the add new item and edit item buttons are hidden for this group.

KanbanState objects provide these fields:

  • Content: usually a string specifying the state's name;
  • Template: optionally, a template to be applied for items within this state;
  • IsCollapsed, IsExpanded: indicate whether the state column is collapsed/expanded (expanded by default);
  • IsCollapsible: when set to false, hides the collapse/expand buttons for this state (applicable when KanbanBoard.AreStateExpandersVisible setting is true);
  • Tag: indicating any object that is to be attached to this state.

An ItemType object defines:

  • HandleBrush, Background, Foreground: appearance properties for items of this type;
  • Template, ContentTemplate: optionally, a template or content template to be applied for items of this type;
  • Tag: indicating any object that is to be attached to this item type.

KanbanResource instances offer these fields:

  • Content: usually a string specifying the resource's name (such as a person's full name or a material resource's abbreviation);
  • ImageSource: the resource's icon;
  • Tag: indicating any object that is to be attached to this resource.

Finally, KanbanCategory provide:

  • Content: usually a string specifying the category name or abbreviation;
  • BorderBrush, Background, Foreground: appearance properties for the category's indicator elements;
  • Tag: indicating any object that is to be attached to this category.

Here we initialize states, resources, categories, groups, and items to be presented within a KanbanBoard:


var state1 = new KanbanState { Content = "New" };
var state2 = new KanbanState { Content = "In progress", AreNewItemButtonsHidden = true };
var state3 = new KanbanState { Content = "Done", IsCollapsedByDefaultForGroups = true, AreNewItemButtonsHidden = true };
var states = new ObservableCollection<KanbanState> { state1, state2, state3 };

var resource1 = new KanbanResource { Content = "Resource 1", ImageSource = new BitmapImage(new Uri("pack://application:,,,/KanbanBoardSample;component/Images/Resource1.png", UriKind.RelativeOrAbsolute)) };
var resource2 = new KanbanResource { Content = "Resource 2", ImageSource = new BitmapImage(new Uri("pack://application:,,,/KanbanBoardSample;component/Images/Resource2.png", UriKind.RelativeOrAbsolute)) };
var resources = new ObservableCollection<KanbanResource> { resource1, resource2 };

var category1 = new KanbanCategory { Content = "Category 1", Background = Brushes.CornflowerBlue, BorderBrush = Brushes.Blue, Foreground = Brushes.White };
var category2 = new KanbanCategory { Content = "Category 2", Background = Brushes.LightGreen, BorderBrush = Brushes.Green };
var category3 = new KanbanCategory { Content = "Category 3", Background = Brushes.LightGreen, BorderBrush = Brushes.Green };
var category4 = new KanbanCategory { Content = "Category 4", Background = Brushes.LightGreen, BorderBrush = Brushes.Green };
var categories = new ObservableCollection<KanbanCategory> { category1, category2, category3, category4 };

var group1 = new KanbanGroup { Content = "Story 1", State = state2, Resources = new ObservableCollection<KanbanResource> { resource1 }, Categories = new ObservableCollection<KanbanCategory> { category1 }, ImageSource = new BitmapImage(new Uri("pack://application:,,,/KanbanBoardSample;component/Images/Group.png", UriKind.RelativeOrAbsolute)) };
var group2 = new KanbanGroup { Content = "Story 2", State = state3, Resources = new ObservableCollection<KanbanResource> { resource1, resource2 } };
var groups = new ObservableCollection<KanbanGroup> { group1, group2 };

var items = new ObservableCollection<KanbanItem>
{
    new KanbanItem { Content = "Task 1", Description = "A long long long long description of task 1", Group = group1, State = state1, Resources = new ObservableCollection<KanbanResource> { resource1, resource2 }, Categories = new ObservableCollection<KanbanCategory> { category2 } },
    new KanbanItem { Content = "Task 2", Group = group1, State = state2, Resources = new ObservableCollection<KanbanResource> { resource1 }, Categories = new ObservableCollection<KanbanCategory> { category1, category2 }, ImageSource = new BitmapImage(new Uri("pack://application:,,,/KanbanBoardSample;component/Images/Item.png", UriKind.RelativeOrAbsolute)) },
    new KanbanItem { Content = "Bug 1", Group = group1, State = state2, Resources = new ObservableCollection<KanbanResource> { resource1 }, ItemType = KanbanBoard.BugItemType },
    new KanbanItem { Content = "Task 3", Group = group1, State = state1 },
    new KanbanItem { Content = "Task 4", Group = group1, State = state1, Resources = new ObservableCollection<KanbanResource> { resource1 }, Date = DateTime.Today.AddDays(3) },
    new KanbanItem { Content = "Task 5", Group = group2, State = state1, Resources = new ObservableCollection<KanbanResource> { resource2 } },
    new KanbanItem { Content = "Task 6", Group = group2, State = state2, Resources = new ObservableCollection<KanbanResource> { resource2 } },
    new KanbanItem { Content = "Task 7", Group = group2, State = state2, Resources = new ObservableCollection<KanbanResource> { resource1 } },
    new KanbanItem { Content = "Task 8", Group = group2, State = state3, Resources = new ObservableCollection<KanbanResource> { resource2 } },
};

KanbanBoard.States = states;
KanbanBoard.Groups = groups;
KanbanBoard.Items = items;
KanbanBoard.AvailableCategories = categories;
KanbanBoard.AvailableResources = resources;
                                

You may supplementary customize KanbanItem objects using classic inheritance and new properties, if needed:


public class CustomKanbanItem : KanbanItem
{
    public string MyProperty { get; set; }
}

                                

KanbanBoard.Items.Add(
    new CustomKanbanItem { Content = "My task", Group = group1, State = state1, MyProperty = "My special value" });

                                

To customize the way item bars displays content, you can redefine ItemContentHeaderTemplate and ItemContentBodyTemplate properties of the component. Examples below are based on the defaults. You may also refer custom item properties from bindings within the data templates:


<kl:KanbanBoard.ItemHeaderTemplate>
    <DataTemplate DataType="local:KanbanItem">
        <StackPanel>
            <Grid Name="CategoriesPanel" Margin="{Binding FieldPadding, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Visibility="{Binding CategoriesVisibility, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}">
                <ItemsControl ItemsSource="{Binding Categories}" Margin="0,4,0,-2">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel IsItemsHost="True"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate DataType="local:KanbanCategory">
                            <Border MinHeight="16" MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
                                    Margin="0,0,6,6" CornerRadius="{Binding CategoryIndicatorCornerRadius, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Padding="4,2"
                                    Background="{Binding Background}" BorderBrush="{Binding BorderBrush}" BorderThickness="{Binding CategoryIndicatorBorderThickness, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" TextElement.FontSize="12">
                                <TextElement.Foreground>
                                    <MultiBinding Converter="{StaticResource ValueConverter}">
                                        <Binding Path="Foreground"/>
                                        <Binding Path="Foreground" RelativeSource="{RelativeSource AncestorType=local:KanbanBoard}"/>
                                    </MultiBinding>
                                </TextElement.Foreground>
                                <TextBlock Text="{Binding Content}" TextTrimming="CharacterEllipsis"/>
                            </Border>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </Grid>
        </StackPanel>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Categories.Count, FallbackValue=0}" Value="0">
                <Setter TargetName="CategoriesPanel" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</kl:KanbanBoard.ItemHeaderTemplate>
<kl:KanbanBoard.ItemBodyTemplate>
    <DataTemplate DataType="local:KanbanItem">
        <StackPanel>
            <Grid Visibility="{Binding DescriptionVisibility, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}">
                <Grid Name="DescriptionPanel" Margin="{Binding FieldPadding, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}"
                      TextElement.FontSize="12">
                    <TextBlock Name="DescriptionTextBlock" Text="{Binding Description}" Background="Transparent" Padding="2" TextTrimming="CharacterEllipsis"
                               MaxHeight="68"/>
                    <TextBox Name="DescriptionTextBox" Text="{Binding Description, UpdateSourceTrigger=PropertyChanged}" Background="Transparent" BorderThickness="0" Padding="0,2" Visibility="Hidden" IsReadOnly="{Binding IsItemContentReadOnly, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" ToolTip="{Binding DescriptionToolTipContent, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}"
                             AcceptsReturn="True" MaxHeight="68"/>
                    <TextBlock Name="DescriptionPlaceHolder" Text="{Binding DescriptionPlaceHolder, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Padding="2" Visibility="Collapsed"
                               Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
                               Opacity="0.8" IsHitTestVisible="False"/>
                </Grid>
            </Grid>
            <Grid Margin="{Binding FieldPadding, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}"
                  TextElement.FontSize="12">
                <TextBlock Text="{Binding MyProperty}" Background="Transparent" Padding="2" TextTrimming="CharacterEllipsis"/>
            </Grid>
            <Grid Visibility="{Binding ItemDateVisibility, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}">
                <StackPanel Name="ItemDatePanel" Margin="{Binding FieldPadding, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}">
                    <DockPanel Margin="0,4" TextElement.FontSize="12">
                        <DatePicker Name="ItemDatePicker" DockPanel.Dock="Left" SelectedDate="{Binding Date}" BorderThickness="0" Background="Transparent" Padding="0" Width="25" Margin="-1" Opacity="0.8"/>
                        <ToggleButton IsChecked="{Binding IsDropDownOpen, ElementName=ItemDatePicker}">
                            <ToggleButton.Template>
                                <ControlTemplate TargetType="ToggleButton">
                                    <ContentPresenter/>
                                </ControlTemplate>
                            </ToggleButton.Template>
                            <Grid HorizontalAlignment="Left" Margin="3,2,0,0">
                                <TextElement.Foreground>
                                    <MultiBinding Converter="{StaticResource ValueConverter}">
                                        <Binding Path="Foreground"/>
                                        <Binding Path="DefaultItemType.Foreground" RelativeSource="{RelativeSource AncestorType=local:KanbanBoard}"/>
                                        <Binding Path="Foreground" RelativeSource="{RelativeSource AncestorType=local:KanbanBoard}"/>
                                    </MultiBinding>
                                </TextElement.Foreground>
                                <TextBlock Name="ItemDateTextBlock" Text="{Binding Date, StringFormat=d}"/>
                                <TextBlock Name="ItemDatePlaceHolder" Text="{Binding ItemDatePlaceHolder, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Visibility="Collapsed"
                                           Foreground="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"
                                           Opacity="0.8" IsHitTestVisible="False"/>
                            </Grid>
                        </ToggleButton>
                    </DockPanel>
                </StackPanel>
            </Grid>
            <StackPanel Name="ResourcesPanel" Margin="{Binding FieldPadding, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Visibility="{Binding ResourcesVisibility, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}">
                <Separator Margin="-8,4" Background="#f0f0f0"/>
                <ItemsControl ItemsSource="{Binding Resources}" Margin="0,4,0,-4">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel IsItemsHost="True"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate>
                        <DataTemplate DataType="local:KanbanResource">
                            <Border Margin="0,0,0,4" TextElement.FontSize="12">
                                <DockPanel>
                                    <Image DockPanel.Dock="Left" Name="Image" Source="{Binding ImageSource}" Width="{Binding ResourceImageSize, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Height="{Binding ResourceImageSize, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}, FallbackValue=0}" Stretch="UniformToFill"
                                           ToolTip="{Binding Content}" Clip="{Binding ResourceImageSize, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}, Converter={StaticResource EllipseGeometryConverter}}" Margin="0,0,4,0"/>
                                    <TextBlock Name="ContentPresenter" Text="{Binding Content}" TextTrimming="CharacterEllipsis" Visibility="Collapsed" VerticalAlignment="Center" Margin="4"/>
                                </DockPanel>
                            </Border>
                            <DataTemplate.Triggers>
                                <DataTrigger Binding="{Binding ImageSource}" Value="{x:Null}">
                                    <Setter TargetName="Image" Property="Visibility" Value="Collapsed"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding DataContext.Resources.Count, RelativeSource={RelativeSource AncestorType=ItemsControl}}" Value="1">
                                    <Setter TargetName="Image" Property="ToolTip" Value="{x:Null}"/>
                                    <Setter TargetName="ContentPresenter" Property="Visibility" Value="Visible"/>
                                </DataTrigger>
                            </DataTemplate.Triggers>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </StackPanel>
        </StackPanel>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Description.Length, FallbackValue=0}" Value="0">
                <Setter TargetName="DescriptionPlaceHolder" Property="Visibility" Value="Visible"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Date}" Value="{x:Null}">
                <Setter TargetName="ItemDatePlaceHolder" Property="Visibility" Value="Visible"/>
            </DataTrigger>
            <Trigger SourceName="DescriptionPanel" Property="IsMouseOver" Value="True">
                <Setter TargetName="DescriptionTextBox" Property="Visibility" Value="Visible"/>
                <Setter TargetName="DescriptionTextBlock" Property="Visibility" Value="Hidden"/>
            </Trigger>
            <Trigger SourceName="DescriptionPanel" Property="IsKeyboardFocusWithin" Value="True">
                <Setter TargetName="DescriptionTextBox" Property="Visibility" Value="Visible"/>
                <Setter TargetName="DescriptionTextBlock" Property="Visibility" Value="Hidden"/>
            </Trigger>
            <DataTrigger Binding="{Binding IsReadOnly}" Value="True">
                <Setter TargetName="DescriptionTextBox" Property="Visibility" Value="Hidden"/>
                <Setter TargetName="DescriptionTextBlock" Property="Visibility" Value="Visible"/>
                <Setter TargetName="ItemDatePicker" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Group.IsReadOnly}" Value="True">
                <Setter TargetName="DescriptionTextBox" Property="Visibility" Value="Hidden"/>
                <Setter TargetName="DescriptionTextBlock" Property="Visibility" Value="Visible"/>
                <Setter TargetName="ItemDatePicker" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding State.IsReadOnly}" Value="True">
                <Setter TargetName="DescriptionTextBox" Property="Visibility" Value="Hidden"/>
                <Setter TargetName="DescriptionTextBlock" Property="Visibility" Value="Visible"/>
                <Setter TargetName="ItemDatePicker" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}" Value="True">
                <Setter TargetName="DescriptionTextBox" Property="Visibility" Value="Hidden"/>
                <Setter TargetName="DescriptionTextBlock" Property="Visibility" Value="Visible"/>
                <Setter TargetName="ItemDatePicker" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsGroup}" Value="True">
                <Setter TargetName="ResourcesPanel" Property="Visibility" Value="{Binding GroupResourcesVisibility, RelativeSource={RelativeSource AncestorType=local:KanbanBoard}}"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Resources.Count, FallbackValue=0}" Value="0">
                <Setter TargetName="ResourcesPanel" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding IsGroup}" Value="True">
                <Setter TargetName="ItemDatePanel" Property="Visibility" Value="Collapsed"/>
            </DataTrigger>
            <Trigger SourceName="ItemDatePicker" Property="IsDropDownOpen" Value="True">
                <Setter TargetName="ItemDateTextBlock" Property="Foreground" Value="Black"/>
            </Trigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</kl:KanbanBoard.ItemBodyTemplate>
                                

Settings

Besides defining Items, States, Groups, GroupStates, AvailableCategories, and AvailableResources, you may fully customize the settings of the Kanban board by providing specific values for its multiple properties:

  • GroupsVisibility: indicates whether group headers are shown in the diagram (Collapsed by default if there is a single, default, group, or Visible if items have group references defined);
  • GroupWidth, StateWidth: configure the widths of group headers and state columns in the diagram;
  • AreStateExpandersVisible, CollapsedStateWidth: configure whether states can be collapsed (as entire columns), and the width of the collapsed state column;
  • AutoStateResizing: if set to true allows the component to automatically compute and update StateWidth property according to the available horizontal space (true by default);
  • LoadsItemsAsynchronously (and ~AfterCount, ~InChunksOfCount): indicates whether the component can load items asynchronously to improve responsiveness (and configures the number of items to start asynchronous loading at, and the size of the chunks loaded at once asynchronously); asynchronous mode is turned on by default (starting after 16 items, loading chunks of 8 items); asynchronous loading mode works like this: the first objects in Items collection are processed synchronously, the rest of items are then moved into AsyncItems list, and then chunks of items are processed from there in the background, moving them back to the original collection as well;
  • LinePadding, ItemPadding, FieldPadding: define spacing for item rows, within item bars, and between fields inside the bar template, respectively;
  • ItemTemplate, GroupTemplate: the main templates for items and groups presented in the diagram; by default they present items and groups using bars with left handler areas allowing drag and drop operations;
  • ItemContentTemplate, GroupContentTemplate: allow customizing the content displayed for standard items and for groups (row headers), when the default ItemTemplate and GroupTemplate definitions are used;
  • ItemBodyTemplate, ItemHeaderTemplate: allow customizing the field area displayed for items and groups, and for item headers, respectively, when the default ItemContentTemplate, GroupContentTemplate, ItemTemplate, and GroupTemplate definitions are used;
  • StateTemplate: the template for states (column headers) presented in the diagram;
  • PopupMenuTemplate: defines the way pop-up menus look like for items; menus are displayed when UsePopupMenus is set to true (default case);
  • NewItemButtonTemplate, EditItemButtonTemplate: define the way new item and edit item buttons – that trigger pop-up menus – appear;
  • DescriptionVisibility, ItemDateVisibility: set up visibility conditions for description and item date fields in the body of an item's content area;
  • CategoriesVisibility, ResourcesVisibility, GroupResourcesVisibility: set up visibility conditions for categories and resources (for standard items and for groups, respectively);
  • ItemImageSize: specifies the size of item icons (default: 32);
  • ResourceImageSize, ResourceImageVisibility: specify the size of resource icons (default: 32), and set up visibility conditions for resource icons, respectively;
  • IsGroupStateHidden, AreGroupStateMenuItemsHidden: indicate whether the combo box allowing the end user to change the state of a group is hidden (default: true), or whether state menu items are hidden, respectively (and independently);
  • AreEditMenuItemsHidden, AreDeleteMenuItemsHidden, AreEditGroupMenuItemsHidden, AreDeleteGroupMenuItemsHidden: indicate whether edit and delete menu items are hidden (for standard items and for groups, respectively);
  • CollapsedGroupItemCountVisibililty: set up visibility conditions for child item counters displayed by default when groups are collapsed;
  • EditMenuItemContent, StateMenuItemContent, CategoriesMenuItemContent, ResourcesMenuItemContent, DeleteMenuItemContent: localizable strings to be displayed for specific menu items;
  • ItemsLabelContent, NoItemsLabelContent: localizable strings to be displayed for item counters and when there are no items to be displayed in the diagram, respectively;
  • IsReadOnly, IsItemContentReadOnly, IsItemGroupReadOnly, AreItemsReadOnly, AreGroupsReadOnly: configure different read only settings for items and groups;
  • AreNewItemButtonsHidden, AreNewItemButtonsAtTop, AreEditItemButtonsHidden, AreEditGroupButtonsHidden: configure new item and edit buttons;
  • NewItemButtonContent, NewItemButtonToolTipContent, EditItemButtonContent, EditItemButtonToolTipContent, EditGroupButtonContent, EditGroupButtonToolTipContent: localizable strings for new item and edit buttons and their tool tips;
  • NewItemContent, NewItemResource: localizable string for new item content, and an optional resource object to automatically assign upon item creation, respectively;
  • DescriptionPlaceHolder, DescriptionToolTipContent, ItemDateToolTipContent: localizable strings for description field's placeholder and description and item date fields' tool tips;
  • ItemAreaBackground, ItemAreaCornerRadius, ItemBorderBrush, ItemBorderThickness, ItemCornerRadius, StateHoveringBackground, GroupHoveringBackground, ItemMoveIndicatorBrush, CategoryIndicatorBorderThickness, CategoryIndicatorCornerRadius: configure miscellaneous appearance settings for diagram elements.

These methods can be called on KanbanBoard component to perform certain operations:

  • SetItemState, SetItemGroup: move items around to different state or group in the diagram;
  • ShowPopupMenu(item): shows the pop-up menu for the specified item;
  • AddNewItem(group, state): creates and adds a new item to the diagram, within the specified group and being displayed on the corresponding state; the new item is returned by the method, but can also be accessed later using NewlyAddedItem property;
  • FindElement(item): returns the visual WPF element of the specified item;
  • ItemsInGroup(group), ItemsInState(state), ItemsInGroupAndState(group, state): enumerate the items within the specified group, having the specified state, or applying these conditions together.

Finally, these events are raised by KanbanBoard component in certain situations:

  • NewItemAdded: raised when a new item is created in the diagram using an add new item button;
  • EditingItem, EditingGroup: raised when standard items or groups are edited, either by clicking their edit button (if UsePopupMenus is false) or by selecting the corresponding edit menu item from the pop-up menu otherwise;
  • DeletingItem, DeletingGroup: raised when an item or group is about to be deleted (upon selecting the corresponding delete menu item from the pop-up menu); allows the developer to cancel the event by setting e.Cancel to true (e represents the event arguments object);
  • DeletedItem, DeletedGroup: raised when an item or group has been deleted from the diagram;
  • MovingItem, MovingGroup: raised when an item or group is about to be moved around in the diagram; allows the developer to cancel the event by setting e.Cancel to true (e represents the event arguments object);
  • ItemStateChanged, ItemGroupChanged, ItemIndexChanged, GroupIndexChanged: raised when specific State, Group or collection index values changes for an item or group.

Here is a configuration example where we customize a few appearance settings and also add handlers for ItemStateChanged and ItemGroupChanged events (occurring when item drag and drop operations complete):


<kl:KanbanBoard Name="KanbanBoard" FontSize="13"
                Background="#f3f6f4" ItemAreaBackground="#90d9eeff"
                BorderBrush="#6485c5" BorderThickness="1" Padding="1"
                ItemBorderBrush="#6485c5" ItemBorderThickness="1"
                StateHoveringBackground="#e0e0e0" GroupHoveringBackground="#616d85" 
                ItemMoveIndicatorBrush="#a09020"
                AreNewItemButtonsHidden="True"
                AreEditGroupButtonsHidden="True" AreEditItemButtonsHidden="True"
                ItemStateChanged="KanbanBoard_ItemStateChanged" ItemGroupChanged="KanbanBoard_ItemGroupChanged"/>
                                

private void KanbanBoard_ItemStateChanged(object sender, KanbanItemStateEventArgs e)
{
    Console.WriteLine("State of item {0} has changed to {1}.", e.Item.Content, e.State.Content);
}

private void KanbanBoard_ItemGroupChanged(object sender, KanbanItemGroupEventArgs e)
{
    Console.WriteLine("Group of item {0} has changed to {1}.", e.Item.Content, e.Group.Content);
}