KinloControls 1.3.15
dotnet add package KinloControls --version 1.3.15
NuGet\Install-Package KinloControls -Version 1.3.15
<PackageReference Include="KinloControls" Version="1.3.15" />
<PackageVersion Include="KinloControls" Version="1.3.15" />
<PackageReference Include="KinloControls" />
paket add KinloControls --version 1.3.15
#r "nuget: KinloControls, 1.3.15"
#:package KinloControls@1.3.15
#addin nuget:?package=KinloControls&version=1.3.15
#tool nuget:?package=KinloControls&version=1.3.15
KinloControls 使用说明书
KinloControls 是面向 .NET 8 WPF 的自定义控件库,适用于自动化设备、生产看板和桌面管理软件,包含选择器、导航、页面动画、仪表盘、时间轴及常用绑定工具。
1. 引用与命名空间
- 目标框架:
net8.0-windows - UI 框架:WPF
- 控件命名空间:
KinloControls - 工具命名空间:
KinloControls.Tools
<ProjectReference Include="..\KinloControls\KinloControls.csproj" />
xmlns:kc="clr-namespace:KinloControls;assembly=KinloControls"
xmlns:kct="clr-namespace:KinloControls.Tools;assembly=KinloControls"
默认样式已通过 Themes/Generic.xaml 注册,正常引用程序集后无需手动合并主题字典。
从 NuGet 安装当前版本:
dotnet add package KinloControls --version 1.3.13
2. 控件总览
| 控件 | 用途 |
|---|---|
ClockPicker |
时、分、秒选择器 |
SliderControl |
带滑块动画的横向单选控件 |
VerticalNav |
可展开、收缩的垂直导航 |
SlidingContentControl |
页面或内容切换动画容器 |
HourlyTimeAxis |
小时产量轴和当前小时定位 |
TimelineChart |
普通状态时间轴 |
OverlappingStateTimelineChart |
多状态重叠时间轴 |
NeonGauge |
带刻度和霓虹效果的仪表盘 |
MinimalGauge |
精简仪表盘 |
3. ClockPicker 时间选择器
Time 默认双向绑定,有效范围为 00:00:00~23:59:59。
<kc:ClockPicker Width="260"
Title="启动时间"
TitleWidth="90"
Time="{Binding StartTime, Mode=TwoWay}"
CornerRadius="6"
IconBackground="#326CF3" />
| 属性 | 默认值 | 说明 |
|---|---|---|
Time |
08:00:00 |
当前时间 |
Title |
空字符串 | 左侧标题 |
TitleWidth |
* |
标题列宽 |
IconBackground |
系统高亮色 | 下拉按钮颜色 |
CornerRadius |
6 |
输入框圆角 |
4. SliderControl 滑块选择器
用于工序、页面或数据分类选择。SelectedIndex 和 SelectedItem 默认双向绑定;没有绑定选择项时,有数据会默认选中第一项。
<kc:SliderControl ItemsSource="{Binding Processes}"
DisplayMemberPath="Description"
SelectedIndex="{Binding SelectedProcessIndex, Mode=TwoWay}"
SliderBackground="{StaticResource PrimaryBrush}"
SliderCornerRadius="5"
TabHorizontalAlignment="Left"
TabWidth="105" />
| 属性 | 默认值 | 说明 |
|---|---|---|
ItemsSource |
null |
选项数据源 |
DisplayMemberPath |
空 | 显示字段名 |
ItemTemplate |
null |
自定义选项内容;设置后优先于 DisplayMemberPath |
SideContent |
null |
左侧或右侧的附加内容,可放按钮或图标 |
SideContentTemplate |
null |
附加内容的数据模板 |
SideContentWidth |
0 |
附加区域宽度;设置后即使无内容也会预留空白 |
SideContentPlacement |
Right |
附加区域位置:Left 或 Right |
SelectedIndex |
0 |
当前索引 |
SelectedItem |
null |
当前数据项 |
ItemStyle |
默认按钮样式 | 选项按钮样式 |
ItemPadding |
12,4 |
每个选项内容周围的内边距 |
Padding |
4 |
选项区域与控件外框之间的内边距 |
TabWidth |
Auto |
每个选项的统一宽度;未设置时各项按内容和 ItemPadding 自适应,超出可用宽度时自动换行 |
TabHorizontalAlignment |
Stretch |
选项区域对齐方式 |
VerticalAlignment |
Center |
默认按内容高度布局并在父容器中垂直居中;设为 Stretch 时随父容器拉伸 |
SliderBackground |
Gray |
选中滑块颜色 |
SliderCornerRadius |
6 |
滑块圆角 |
CornerRadius |
8 |
控件外框圆角 |
BackgroundOpacity |
1 |
背景透明度 |
默认不指定 Height 时,控件外框高度由 Item 的内容高度、ItemPadding 和控件 Padding 共同决定。例如下面的设置会为每个 Item 添加水平内边距,并在 Item 与外框之间保留 4 像素间距:
<kc:SliderControl ItemPadding="10,2"
Padding="4" />
需要显示复合内容时使用 ItemTemplate,不要覆盖 SliderControl.Template,否则会移除滑块所需的模板部件。模板的数据上下文是当前数据项,内部按钮可以正常执行命令:
<kc:SliderControl ItemsSource="{Binding Processes}"
ItemPadding="15,4"
SelectedIndex="{Binding SelectedProcessIndex, Mode=TwoWay}">
<kc:SliderControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center"
Text="{Binding ProcName}" />
<Button Grid.Column="1"
Command="{Binding OpenLogCommand}"
CommandParameter="{Binding}"
Content="查看" />
</Grid>
</DataTemplate>
</kc:SliderControl.ItemTemplate>
</kc:SliderControl>
点击选项会统一更新 SelectedIndex、文字状态和滑块位置;即使页面上有刚关闭的 Popup,也不会只改变文字颜色而遗漏选择状态。点击 ItemTemplate 内部按钮不会触发选项切换。
需要在 Tab 左侧或右侧放置其他控件时,使用附加内容区域。下面会在右侧预留 72 像素并放置菜单按钮:
<kc:SliderControl ItemsSource="{Binding Processes}"
DisplayMemberPath="Description"
SideContentPlacement="Right"
SideContentWidth="72">
<kc:SliderControl.SideContent>
<Button Command="{Binding OpenMenuCommand}"
Content=""
FontFamily="Segoe MDL2 Assets" />
</kc:SliderControl.SideContent>
</kc:SliderControl>
只需要留出空白而暂时不放内容时:
<kc:SliderControl SideContentPlacement="Left"
SideContentWidth="60" />
选择事件:
<kc:SliderControl SelectionChanged="Slider_SelectionChanged" />
private void Slider_SelectionChanged(object sender, KinloControls.SelectionChangedEventArgs e)
{
var oldItem = e.OldItem;
var newItem = e.NewItem;
}
固定时长动画(兼容旧版本的默认模式):
<kc:SliderControl AnimationDurationMode="Fixed"
AnimationDuration="0:0:0.3" />
按距离计算动画,近距离快、远距离慢:
<kc:SliderControl AnimationDurationMode="ByDistance"
AnimationPixelsPerSecond="800"
MinimumAnimationDuration="0:0:0.08"
MaximumAnimationDuration="0:0:0.5" />
| 动画属性 | 默认值 | 说明 |
|---|---|---|
AnimationDurationMode |
Fixed |
Fixed 或 ByDistance |
AnimationDuration |
300ms |
固定模式时长 |
AnimationPixelsPerSecond |
800 |
距离模式速度,必须大于 0 |
MinimumAnimationDuration |
80ms |
距离模式最短时长 |
MaximumAnimationDuration |
500ms |
距离模式最长时长 |
连续快速切换时,新动画从滑块当前视觉位置转向新目标,不会跳回旧起点。
5. VerticalNav 垂直导航
支持图标、文字、选中项、页头页脚,以及鼠标移入展开、移出收缩。
<kc:VerticalNav ItemsSource="{Binding Menus}"
DisplayMemberPath="Title"
IconMemberPath="Icon"
SelectedIndex="{Binding SelectedMenuIndex, Mode=TwoWay}"
ItemHeight="44"
ItemMargin="4,2"
ItemCornerRadius="6"
ShrinkWidth="64"
ExpandWidth="220"
ShrinkDelay="300" />
| 属性 | 默认值 | 说明 |
|---|---|---|
Header / Footer |
null |
顶部、底部内容 |
ItemsSource |
null |
导航数据源 |
DisplayMemberPath |
空 | 文字字段名 |
IconMemberPath |
空 | 图标字段名 |
SelectedIndex |
-1 |
当前索引,默认双向绑定 |
ItemHeight |
40 |
导航项高度 |
ItemMargin |
3,0,3,0 |
导航项间距 |
ItemCornerRadius |
6 |
导航项圆角 |
ShrinkWidth |
60 |
收缩宽度;旧名称 ShinkWidth 仍兼容 |
ExpandWidth |
200 |
展开宽度 |
ShrinkDelay |
0ms |
鼠标离开后的收缩延迟 |
IconFontFamily |
null |
图标字体 |
IconFontSize |
15 |
图标字号 |
CornerRadius |
8 |
外框圆角 |
SelectionChanged 事件用法与 SliderControl 相同。
6. SlidingContentControl 页面切换
内容改变时保留上一页并播放过渡动画,适合绑定当前页面或视图模型。
<kc:SlidingContentControl Content="{Binding CurrentPage}"
Slide="Up"
ShakeMode="Rebound"
TransitionDuration="0:0:0.42"
ShakeAmplitude="8"
ShakeDelayRatio="0.72" />
| 属性 | 默认值 | 说明 |
|---|---|---|
Slide |
Up |
Up 或 Down |
ShakeMode |
Rebound |
None、Rebound、Displace、ShakeX |
TransitionDuration |
420ms |
设置为 0 可关闭动画 |
ShakeAmplitude |
8 |
回弹或抖动幅度,不能为负数 |
ShakeDelayRatio |
0.72 |
动画阶段分界,自动限制在 0~1 |
PreviousContent |
null |
动画期间的上一内容,通常无需设置 |
快速切页时控件会停止旧动画,并忽略已经过期的延迟动画任务。
7. HourlyTimeAxis 小时时间轴
展示小时产量,自动识别并定位当前小时。支持鼠标拖动和滚轮浏览;用户空闲约 10 秒后重新定位当前小时。
<kc:HourlyTimeAxis ItemsSource="{Binding HourlyItems}" />
public ObservableCollection<HourlyData> HourlyItems { get; } =
[
new HourlyData
{
Time = DateTime.Today.AddHours(8),
Subtitle = "08时",
InputCount = 120,
ProductionCount = 116,
InputPrefix = "进 ",
ValuePrefix = "出 "
}
];
HourlyData 包含:
Time、只读Hour、IsCurrentHourInputCount、InputPrefix、InputSuffix、只读InputDisplayValueProductionCount、ValuePrefix、ValueSuffix、只读DisplayValueSubtitle
IsCurrentHour 由控件自动维护。
8. TimelineChart 普通时间轴
适合展示设备运行、报警、待机等状态区间,支持悬浮提示、缩放、拖动及图例统计。
<kc:TimelineChart Header="设备状态"
CornerRadius="8"
TimelineItems="{Binding TimelineItems}" />
public ObservableCollection<TimelineItem> TimelineItems { get; } =
[
new TimelineItem
{
Id = 1,
Label = "运行",
StartTime = DateTime.Today.AddHours(8),
EndTime = DateTime.Today.AddHours(9),
Color = Brushes.LimeGreen,
Message = "正常生产",
IsFinish = true
}
];
TimelineItem 包含 Id、Value、Label、StartTime、EndTime、Color、Message 和 IsFinish。
9. OverlappingStateTimelineChart 重叠时间轴
用于同一时间点可能存在多个状态的场景,通过时间切片避免状态互相覆盖,并提供缩放、拖动、悬浮明细和底部统计。
<kc:OverlappingStateTimelineChart Header="并行状态"
CornerRadius="8"
Items="{Binding TimelineItems}" />
数据模型同样使用 TimelineItem。同一时间段有多条记录时会按重叠状态绘制。
10. NeonGauge 霓虹仪表盘
<kc:NeonGauge Width="260" Height="260"
Minimum="0" Maximum="100"
Value="{Binding Pressure}"
UnitText="kPa"
OuterStartAngle="135"
OuterSweepAngle="270"
ProgressWidth="20"
TickLength="15"
TextColor="White" />
默认值:Value=0、Minimum=0、Maximum=100、OuterStartAngle=135、OuterSweepAngle=270、ProgressWidth=20、TickLength=15、UnitText=Kpa、UnitFontSize=11。
ProgressBrush 类型为 LinearGradientBrush,NeedleColor 类型为 Color。应保证 Maximum > Minimum。
11. MinimalGauge 精简仪表盘
<kc:MinimalGauge Width="220" Height="160"
Minimum="0" Maximum="10"
Value="{Binding Flow}"
UnitText="L/min"
OuterStartAngle="150"
OuterSweepAngle="240"
ProgressWidth="16"
NeedleThickess="3" />
默认值:Value=0、Minimum=0、Maximum=100、OuterStartAngle=150、OuterSweepAngle=240、ProgressWidth=16、NeedleThickess=3、UnitText=Kpa、UnitFontSize=11。
注意:公开属性当前名为 NeedleThickess,这是为兼容现有调用保留的拼写。
12. 公共工具
ObservableRangeCollection
位于 KinloControls.Tools,批量操作只发送一次集合重置通知:
var items = new ObservableRangeCollection<DeviceModel>();
items.AddRange(deviceList);
items.RemoveRange(disabledDevices);
items.ReplaceRange(newList);
items.SortBy(x => x.Index);
提供 AddRange、InsertRange、InsertRangeAndTrim、AddRangeAndTrim、RemoveRange、RemoveAtRange、ReplaceRange、Sort 和 SortBy。
这些批量 API 对多元素操作统一发送 Reset,以兼容不支持 Range 集合事件的 WPF 视图;
单元素操作会发送标准的精确 Add/Remove 通知。
如果调用方依赖逐项通知,可使用显式的增量方法,并传入集合视图来延迟排序、筛选等刷新:
ICollectionView view = CollectionViewSource.GetDefaultView(items);
items.AddRangeIncrementally(deviceList, view);
items.RemoveRangeIncrementally(disabledDevices, view);
增量方法仍然只发送 WPF 标准的单项通知,不会发送兼容性较差的多项 Range 事件。
LanguageResource
根据资源键动态设置文字,资源不存在时显示键本身:
<TextBlock kc:LanguageResource.Key="Home_Title" />
<Button kc:LanguageResource.Key="Save_Button" />
默认支持 TextBlock.Text、TextBox.Text、常用内容控件的 Content、标题控件的 Header 和 Window.Title。
ResourceBinding
将普通绑定值解释为动态资源键;资源不存在时尝试直接使用原值:
<Border Background="{kc:ResourceBinding ThemeBrushKey}" />
FuzzyMatcherUniversal
对英文字母、数字和中文字段进行模糊匹配:
var candidates = FuzzyMatcherUniversal.Match(
"inputcount",
new List<(string localField, object tag)>
{
("InputCount", "进站数量"),
("OutputCount", "出站数量")
},
topN: 3,
threshold: 0.25);
返回的 FieldMatchResult 包含 LocalField、Score 和原样返回的 Tag。
13. 自定义模板
复制对应主题中的默认模板后再修改,并保留代码声明的 PART_ 部件:
| 控件 | 关键模板部件 |
|---|---|
ClockPicker |
PART_HourListBox、PART_MinuteListBox、PART_SecondListBox |
SliderControl |
PART_ItemContainer、PART_SliderThumb |
SlidingContentControl |
PART_Previous、PART_Current、PART_Root |
HourlyTimeAxis |
PART_ScrollViewer、PART_ItemsControl |
VerticalNav |
PART_BackgroundBorder、PART_ContentPanel |
MinimalGauge |
PART_ProgressBackArc、PART_ProgressPath、PART_Needle、PART_ValueText |
缺少模板部件时,对应显示或交互能力不可用。
14. 绑定与线程注意事项
SelectedIndex、SelectedItem、ClockPicker.Time默认双向绑定。- 集合建议使用
ObservableCollection<T>或ObservableRangeCollection<T>。 - WPF 集合和绑定对象原则上应在 UI 线程更新。
- 时间轴数据应满足
EndTime >= StartTime。 - 仪表盘应满足
Maximum > Minimum,业务层按需限制Value范围。 - 动态增删数据时,
ItemsSource应实现INotifyCollectionChanged。
15. 构建与 NuGet 发布
发布前先确认 KinloControls.csproj 中的 Version 已更新,并执行 Release 打包:
dotnet clean KinloControls.csproj -c Release
dotnet pack KinloControls.csproj -c Release
生成的包位于:
bin\Release\KinloControls.<版本号>.nupkg
发布到 NuGet.org:
dotnet nuget push "bin\Release\KinloControls.<版本号>.nupkg" `
--api-key "你的 NuGet API Key" `
--source "https://api.nuget.org/v3/index.json"
发布前检查:
- Release 构建没有错误和警告。
.nupkg版本号与项目版本一致。- 包内包含
KinloControls.dll、KinloControls.xml和README.md。 - README 安装命令使用同一个版本号。
- NuGet 已发布的版本不可覆盖;再次发布必须提升版本号。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0-windows7.0 is compatible. net9.0-windows was computed. net10.0-windows was computed. |
-
net8.0-windows7.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.15 | 111 | 9/9/2026 |
| 1.3.13 | 101 | 9/9/2026 |
| 1.3.11 | 97 | 9/7/2026 |
| 1.3.10 | 105 | 9/7/2026 |
| 1.3.9 | 94 | 9/2/2026 |
| 1.3.8 | 93 | 8/27/2026 |
| 1.3.7 | 103 | 8/27/2026 |
| 1.3.6 | 95 | 8/27/2026 |
| 1.3.5 | 100 | 8/27/2026 |
| 1.3.3 | 97 | 8/27/2026 |
| 1.3.2 | 95 | 8/27/2026 |
| 1.3.1 | 94 | 8/27/2026 |
| 1.3.0 | 101 | 8/26/2026 |
| 1.2.9 | 109 | 8/18/2026 |
| 1.2.8 | 129 | 7/2/2026 |
| 1.2.7 | 111 | 7/2/2026 |
| 1.2.6 | 136 | 2/26/2026 |
| 1.2.5 | 121 | 2/26/2026 |
| 1.2.3 | 119 | 2/26/2026 |
| 1.2.2 | 117 | 2/26/2026 |
新增 SliderControl.ItemTemplate、ItemPadding 及可配置左右位置和宽度的 SideContent;修复 Popup 关闭时选项文字、SelectedIndex 与滑块位置不同步;改进批量集合 API。