mcpField
S
syncfusion-wpf-kanban-board

syncfusion-wpf-kanban-board

github.com/syncfusion开发5156 次安装1 周前更新
代码仓库

关于 syncfusion-wpf-kanban-board

面向 WPF 开发者的 Syncfusion SfKanban 看板控件实现指南,用于将任务按工作流阶段组织成卡片和列。内容涵盖泳道、WIP 限制、状态转换规则及卡片拖放。

主要功能

  1. 01按工作流阶段排列任务卡片
  2. 02按团队或项目划分泳道
  3. 03设置列级 WIP 限制
  4. 04拖放卡片及批量移动
  5. 05配置允许的状态转换
  6. 06卡片排序与列重排

适用场景

  1. 01跟踪软件开发任务和缺陷
  2. 02按团队成员组织项目任务
  3. 03限制各工作阶段的任务数量
  4. 04执行受规则约束的任务状态流转

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/syncfusion/wpf-ui-components-skills --skill syncfusion-wpf-kanban-board

安装后在 Claude Code 中输入/syncfusion-wpf-kanban-board确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
cards.md
columns.md
events.md
getting-started.md
sorting.md
swimlanes.md
workflows.md

详细介绍

实现 Syncfusion WPF Kanban(SfKanban)

本技能提供有关实现 Syncfusion® WPF Kanban(SfKanban)控件的全面指南。该控件是一种强大的可视化工作流管理系统,可将任务显示为卡片,并将卡片组织在代表不同工作流阶段的列中。

何时使用此技能

在以下情况中立即使用此技能:

  • 用户想要创建用于任务或项目管理的看板
  • 构建工作流可视化系统(待办、进行中、已完成)
  • 实现敏捷项目跟踪看板
  • 需要为每个工作流阶段设置进行中(WIP)限制
  • 创建支持拖放功能的任务看板
  • 使用泳道按团队、项目或自定义条件组织任务
  • 管理软件开发工作流或问题跟踪系统
  • 需要可视化多个阶段中的任务状态

组件概述

Syncfusion WPF Kanban(SfKanban)可高效地直观呈现工作流各阶段的完成情况。它提供以下功能:

核心功能:

  • 卡片:以可视化方式呈现任务,包含标题、说明、标签、图像和优先级指示器
  • 列:将工作组织到各个工作流阶段(例如,待处理、进行中、已完成)
  • 泳道:按项目、团队、用户或自定义类别对卡片分组
  • 进行中(WIP)限制:为每列设置任务数量的最小值和最大值,避免超负荷
  • 拖放:直观地在列和泳道之间移动卡片,并支持多卡片(批量)拖放
  • 卡片选择:支持单选和多选,并可自定义选中卡片的外观
  • 列重新排序:通过拖放重新排列列
  • 工作流:定义卡片在特定状态之间允许的转换
  • 排序:按优先级、日期或自定义字段对列中的卡片排序
  • 事件:提供丰富的卡片交互事件模型(点击、拖动、放下)
  • 自定义:全面支持自定义卡片、标题和泳道模板
  • 主题:内置浅色和深色主题,并支持系统集成
  • 本地化和 RTL:支持多种语言和从右到左的显示

文档与导航指南

入门

📄 阅读: references/getting-started.md

适用于用户需要:

  • 通过 NuGet 进行初始设置和安装
  • 创建基本看板
  • 了解 ItemsSource 绑定
  • 使用默认 KanbanModel 或自定义数据模型
  • 设置自动生成或手动定义的列
  • 应用主题、本地化和 RTL 支持
卡片配置

📄 阅读: references/cards.md

适用于用户需要:

  • 了解卡片结构和属性
  • 使用 CardTemplate 自定义卡片外观
  • 使用卡片指示器和标签
  • 实现条件卡片模板(CardTemplateSelector)
  • 启用和自定义卡片工具提示
  • 选择单张或多张卡片(CardSelectionType)
  • 通过多卡片拖放批量移动任务
  • 自定义选中卡片的外观(SelectedBorderBrush)
  • 以编程方式获取选中的卡片(GetSelectedCards)
  • 排查卡片显示问题
列管理

📄 阅读: references/columns.md

适用于用户需要:

  • 配置列宽(最小值、最大值、精确值)
  • 在自动生成列与手动定义列之间进行选择
  • 将类别映射到列
  • 自定义列标题
  • 以编程方式展开或折叠列
  • 按列启用或禁用拖放
  • 启用通过拖放重新排列列(AllowColumnReorder)
  • 设置多类别列
  • 配置 WIP(进行中)限制及其可视化指示器
  • 自定义拖放占位符的外观
泳道组织

📄 阅读: references/swimlanes.md

适用于用户需要:

  • 按团队、项目或用户分组卡片
  • 启用和配置泳道
  • 映射泳道属性(SwimlaneKey)
  • 自定义泳道标题的外观
  • 创建分层卡片组织结构
  • 实现基于团队或项目的视图
工作流和状态转换

📄 阅读: references/workflows.md

适用于用户需要:

  • 定义卡片在列之间允许的状态转换
  • 限制卡片在特定状态之间移动
  • 实现工作流验证规则
  • 阻止通过拖放将卡片移动到特定列
  • 创建类似状态机的工作流
  • 管理复杂的工作流状态转换
卡片排序

📄 阅读: references/sorting.md

适用于用户需要:

  • 按优先级、日期或自定义字段对列中的卡片排序
  • 实现自定义字段排序(升序/降序)
  • 设置基于索引的排序,以精确定位
  • 在拖放后动态更新排序顺序
  • 排序变更后刷新列显示
  • 了解如何对自定义数据模型进行排序
事件和交互

📄 阅读: references/events.md

适用于用户需要:

  • 处理卡片点击事件(CardTapped)
  • 响应拖动事件(CardDragStarting、CardDragOver)
  • 处理卡片放置事件(CardDrop)
  • 实现 MVVM 命令(CardTappedCommand)
  • 访问事件参数和卡片数据
  • 阻止或自定义拖放行为
  • 处理卡片选择事件(CardSelected、CardDeselected)
  • 处理列重新排序事件(ColumnDragStarting、ColumnDragOver、ColumnDrop)
  • 在卡片交互中实现业务逻辑

快速入门示例

基本看板设置
<Window xmlns:kanban="clr-namespace:Syncfusion.UI.Xaml.Kanban;assembly=Syncfusion.SfKanban.WPF">
    <kanban:SfKanban x:Name="kanban" 
                     ItemsSource="{Binding TaskDetails}">
        <kanban:SfKanban.DataContext>
            <local:ViewModel/>
        </kanban:SfKanban.DataContext>
    </kanban:SfKanban>
</Window>
使用 KanbanModel 的 ViewModel
using Syncfusion.UI.Xaml.Kanban;

public class ViewModel
{
    public ObservableCollection<KanbanModel> TaskDetails { get; set; }

    public ViewModel()
    {
        TaskDetails = new ObservableCollection<KanbanModel>
        {
            new KanbanModel
            {
                Title = "UWP Issue",
                ID = "651",
                Description = "Fix crosshair label template issue",
                Category = "Open",
                ColorKey = "High",
                Tags = new string[] { "Bug Fixing" }
            },
            new KanbanModel
            {
                Title = "Kanban Feature",
                ID = "25678",
                Description = "Implement drag and drop support",
                Category = "In Progress",
                ColorKey = "Normal",
                Tags = new string[] { "New Feature" }
            }
        };
    }
}
手动定义列
<kanban:SfKanban AutoGenerateColumns="False" 
                 ItemsSource="{Binding TaskDetails}">
    <kanban:KanbanColumn Title="To Do" Categories="Open" />
    <kanban:KanbanColumn Title="In Progress" Categories="In Progress" />
    <kanban:KanbanColumn Title="Done" Categories="Done" />
</kanban:SfKanban>

常见模式

模式 1:自动生成列

适用场景: 用户希望根据数据快速设置并生成列

// Columns automatically generated from Category property values
kanban.AutoGenerateColumns = true;
kanban.ItemsSource = viewModel.TaskDetails;

结果: 根据数据中唯一的 Category 值自动创建列

模式 2:使用可视化指示器设置 WIP 限制

适用场景: 用户需要限制每个阶段的任务数量并显示可视化反馈

<kanban:KanbanColumn Title="In Progress" 
                     Categories="In Progress"
                     MinimumLimit="2" 
                     MaximumLimit="5" />

结果:

  • 数量超过 MaximumLimit 时,错误栏显示为红色
  • 数量低于 MinimumLimit 时,错误栏显示为黄色
  • 有助于防止工作流瓶颈
模式 3:自定义卡片模板

适用场景: 用户需要自定义卡片外观,而非使用默认外观

<kanban:SfKanban.CardTemplate>
    <DataTemplate>
        <Border Background="#F3CFCE" 
                BorderThickness="1" 
                CornerRadius="3">
            <StackPanel Margin="10">
                <TextBlock Text="{Binding Title}" 
                          FontWeight="Bold" 
                          FontSize="14" />
                <TextBlock Text="{Binding Description}" 
                          FontSize="12" 
                          TextWrapping="Wrap" />
            </StackPanel>
        </Border>
    </DataTemplate>
</kanban:SfKanban.CardTemplate>

DataContext: KanbanModel 实例

模式 4:按团队划分泳道

适用场景: 用户希望按团队或项目组织卡片

<kanban:SfKanban SwimlaneKey="Assignee" 
                 ItemsSource="{Binding TaskDetails}">
    
</kanban:SfKanban>

结果: 水平泳道行,每个唯一的 Assignee 值对应一行

模式 5:工作流限制

适用场景: 用户希望强制执行特定的卡片状态转换规则

<kanban:SfKanban.Workflows>
    <kanban:KanbanWorkflow Category="Open">
        <kanban:KanbanWorkflow.AllowedTransitions>
            <x:String>In Progress</x:String>
        </kanban:KanbanWorkflow.AllowedTransitions>
    </kanban:KanbanWorkflow>
    <kanban:KanbanWorkflow Category="In Progress">
        <kanban:KanbanWorkflow.AllowedTransitions>
            <x:String>Done</x:String>
            <x:String>Won't Fix</x:String>
        </kanban:KanbanWorkflow.AllowedTransitions>
    </kanban:KanbanWorkflow>
</kanban:SfKanban.Workflows>

结果:

  • “Open”中的卡片只能移至“In Progress”
  • “In Progress”中的卡片只能移至“Done”或“Won't Fix”
  • 防止无效的状态转换
模式 6:自定义数据模型

适用场景: 用户已有现成的数据模型,不使用 KanbanModel

// Custom model
public class TaskDetails
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string Status { get; set; }
}

// XAML
<kanban:SfKanban ItemsSource="{Binding Tasks}"
                 ColumnMappingPath="Status">
    <kanban:SfKanban.CardTemplate>
        
    </kanban:SfKanban.CardTemplate>
</kanban:SfKanban>

重要提示: 使用自定义模型时,必须定义 CardTemplate

模式 7:多卡片选择与批量拖放

适用场景: 用户需要选择多张卡片,并将它们一起移至其他阶段

<kanban:SfKanban CardSelectionType="Multiple"
                 ItemsSource="{Binding TaskDetails}">
    <kanban:SfKanban.CardStyle>
        <kanban:KanbanCardStyle SelectedBorderBrush="Blue"
                                HoverBorderBrush="LightGray"/>
    </kanban:SfKanban.CardStyle>
</kanban:SfKanban>

结果:

  • Ctrl + Click 可将单张卡片添加到选择中或从选择中移除
  • Shift + Click 可选择同一列中的一组卡片
  • 拖动任意已选卡片,即可将所有已选卡片作为单次操作一起移动
  • 放置后,已选卡片的相对顺序保持不变
  • 无效的工作流状态转换会取消整个拖动操作

在代码中获取选择内容:

var selectedCards = kanban.GetSelectedCards();
模式 8:列重排

适用场景: 用户需要在运行时重新排列工作流阶段

<kanban:SfKanban AllowColumnReorder="True"
                 AutoGenerateColumns="False"
                 ItemsSource="{Binding TaskDetails}">
    <kanban:KanbanColumn Title="To Do" Categories="Open" />
    <kanban:KanbanColumn Title="In Progress" Categories="In Progress" />
    <kanban:KanbanColumn Title="Done" Categories="Done" />
</kanban:SfKanban>

结果:

  • 拖动列标题可移动整列(标题和卡片)
  • 列会插入到放置位置,并推动其他列
  • 不设置 AllowColumnReorder 即可禁用(默认值:false)

关键属性

SfKanban 属性
属性类型用途使用场景
ItemsSourceobject卡片的数据源始终使用(必需)
AutoGenerateColumnsbool根据 Category 自动创建列快速设置或自定义控制
ColumnsCollection手动定义列当 AutoGenerateColumns = false 时
ColumnMappingPathstring用于列分类的属性自定义模型(默认值:"Category")
SwimlaneKeystring用于泳道分组的属性按团队/项目组织
CardTemplateDataTemplate自定义卡片外观自定义数据模型或样式
ColumnHeaderTemplateDataTemplate自定义列标题品牌展示或补充信息
SwimlaneHeaderTemplateDataTemplate自定义泳道标题自定义泳道显示
MinColumnWidthdouble最小列宽响应式布局
MaxColumnWidthdouble最大列宽控制列大小
ColumnWidthdouble固定列宽统一列宽
SortingMappingPathstring用于卡片排序的属性按优先级/日期排列卡片
SortingOrderenum升序或降序排序方向
WorkflowsCollection允许的卡片流转工作流验证
IndicatorColorPaletteCollection指示器的颜色映射优先级/状态颜色
IsToolTipEnabledbool启用卡片工具提示悬停时显示卡片补充信息
CardSelectionTypeKanbanCardSelectionType卡片选择模式(Single、Multiple、None)单卡片或多卡片选择
AllowColumnReorderbool启用列的拖放重排(默认值:false)用户自定义列顺序
KanbanColumn 属性
属性类型用途使用场景
Titlestring列的显示名称自定义列标题
Categoriesstring以逗号分隔的类别将数据映射到列
MinimumLimitintWIP 最小限制工作流管理
MaximumLimitintWIP 最大限制防止超载
AllowDragbool启用从列中拖动控制卡片移动
AllowDropbool启用放置到列中限制放置操作
IsExpandedbool列的折叠/展开状态控制 UI 状态
KanbanModel 属性
属性类型描述显示位置
Titlestring卡片标题顶部,粗体文本
IDobject唯一标识符默认 UI 中不显示
Descriptionstring详细文本标题下方
Categoryobject列分配决定列的位置
Assigneestring指派对象用于泳道分组
ColorKeyobject优先级/状态键卡片上的颜色条
Tagsstring[]标签/类别卡片底部
ImageURLUri头像/图标卡片右侧

常见用例

1. 软件开发任务看板

场景: 跟踪 Bug 和功能在各开发阶段中的进展

<kanban:SfKanban ItemsSource="{Binding Issues}">
    <kanban:KanbanColumn Title="Backlog" Categories="Open,New" />
    <kanban:KanbanColumn Title="In Development" 
                         Categories="In Progress" 
                         MaximumLimit="3" />
    <kanban:KanbanColumn Title="Testing" 
                         Categories="Testing" 
                         MaximumLimit="5" />
    <kanban:KanbanColumn Title="Done" 
                         Categories="Closed,Resolved" />
</kanban:SfKanban>
2. 基于团队的项目管理

场景: 使用泳道按团队成员组织任务

<kanban:SfKanban SwimlaneKey="Assignee" 
                 ItemsSource="{Binding ProjectTasks}">
    <kanban:SfKanban.SwimlaneHeaderTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding Image}" Width="30" Height="30"/>
                <TextBlock Text="{Binding Title}" Margin="10,0"/>
            </StackPanel>
        </DataTemplate>
    </kanban:SfKanban.SwimlaneHeaderTemplate>
</kanban:SfKanban>
3. 基于优先级排序

场景: 按优先级对每列中的卡片进行排序

<kanban:SfKanban SortingMappingPath="Priority"
                 SortingOrder="Descending"
                 ItemsSource="{Binding Tasks}"
                 CardDragEnd="OnCardDrop">
    
</kanban:SfKanban>
 private void OnCardDrop(object sender, KanbanDragEndEventArgs e)
 {
     kanban.RefreshKanbanColumn(e.TargetKey.ToString());
 }
4. 交互式卡片操作

场景: 处理卡片点击事件以显示详情对话框

kanban.CardTapped += (s, e) => {
    var card = e.SelectedCard.DataContext as KanbanModel;
    var dialog = new TaskDetailsDialog(card);
    await dialog.ShowAsync();
};

故障排除

问题:列未显示

**症状:**看板为空,没有显示任何列

解决方案:

  1. 确认 AutoGenerateColumns 为 true,或已手动定义 Columns
  2. 检查 ItemsSource 是否正确绑定
  3. 确保数据中的 Category 属性有值
  4. 如果使用 ColumnMappingPath,请确认模型中存在该属性
问题:卡片未显示

**症状:**列已显示,但没有卡片

解决方案:

  1. 检查 ItemsSource 是否包含数据
  2. 确认 Category 值与列的 Categories 匹配
  3. 如果使用自定义模型,请确保已定义 CardTemplate
  4. 检查 DataContext 是否设置正确
问题:拖放不起作用

**症状:**无法在列之间移动卡片

解决方案:

  1. 确认源列的 AllowDrag=true(默认值为 true)
  2. 确保 Workflows 不会限制该转换
  3. 检查列是否映射了正确的 Categories
问题:WIP 限制不起作用

**症状:**未显示 WIP 限制的视觉指示器

解决方案:

  1. 确认已为列设置 MinimumLimit 和/或 MaximumLimit
  2. 检查卡片数量是否确实超出/低于限制
  3. 确保主题资源已正确加载
问题:泳道未分组

**症状:**所有卡片都在同一行,没有泳道

解决方案:

  1. 确认已设置 SwimlaneKey 属性
  2. 检查数据模型中是否存在映射的属性
  3. 确保数据中的属性值各不相同
  4. 如果使用 KanbanModel,默认值为 "Assignee"
问题:排序未生效

**症状:**拖放后卡片未排序

解决方案:

  1. 在 CardDrop 事件中调用 RefreshKanbanColumn()
  2. 确认 SortingMappingPath 设置为有效属性
  3. 检查属性类型是否可排序(string、int、DateTime 等)
  4. 确保已指定 SortingOrder(Ascending/Descending)

最佳实践

  1. 快速入门时使用 KanbanModel:内置模型提供默认卡片 UI,可节省开发时间
  2. 自定义模型需要模板:使用自定义数据模型时,务必定义 CardTemplate
  3. 设置 WIP 限制:实现 MinimumLimit/MaximumLimit,防止工作流出现瓶颈
  4. 通过 CardDrop 处理排序:使用排序功能时,在放置后调用 RefreshKanbanColumn()
  5. 使用 Workflows 进行验证:通过 Workflows 属性阻止无效的状态转换
  6. 优化列宽:为自适应布局设置 MinColumnWidth/MaxColumnWidth
  7. 利用泳道:按逻辑类别(团队、项目、优先级)对卡片分组
  8. 自定义指示器:定义 IndicatorColorPalette,以清晰地显示优先级
  9. 启用工具提示:设置 IsToolTipEnabled=true,以显示更多卡片信息
  10. 测试主题:确认浅色和深色模式下的外观

边缘情况和注意事项

每列包含多个类别:

  • 使用逗号分隔的值:Categories="Open,New,Backlog"
  • 所有匹配的卡片都会显示在同一列中

自定义模型要求:

  • 必须定义 CardTemplate(默认模板要求使用 KanbanModel)
  • 如果属性名不是 "Category",必须设置 ColumnMappingPath
  • 模板的 DataContext 是自定义模型实例

工作流限制:

  • AllowedTransitions 为空 = 不允许放置卡片
  • 未为某个类别定义工作流 = 允许所有转换
  • 工作流中的 Category 必须与数据中的 Category 值完全匹配

拖放排序:

  • 放置后不会自动应用排序
  • 必须在 CardDrop 事件中手动调用 RefreshKanbanColumn()
  • 基于索引的排序需要在事件处理程序中自定义实现

泳道分组:

  • KanbanModel 的默认泳道键为 "Assignee"
  • 自定义模型必须显式设置 SwimlaneKey
  • Null 或空值会创建一个名为 "ungrouped" 的泳道

评论

支持 Markdown