KinloControls 1.3.15

dotnet add package KinloControls --version 1.3.15
                    
NuGet\Install-Package KinloControls -Version 1.3.15
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="KinloControls" Version="1.3.15" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KinloControls" Version="1.3.15" />
                    
Directory.Packages.props
<PackageReference Include="KinloControls" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add KinloControls --version 1.3.15
                    
#r "nuget: KinloControls, 1.3.15"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package KinloControls@1.3.15
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=KinloControls&version=1.3.15
                    
Install as a Cake Addin
#tool nuget:?package=KinloControls&version=1.3.15
                    
Install as a Cake Tool

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="&#xE700;"
                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、IsCurrentHour
  • InputCount、InputPrefix、InputSuffix、只读 InputDisplayValue
  • ProductionCount、ValuePrefix、ValueSuffix、只读 DisplayValue
  • Subtitle

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 Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • 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
Loading failed

新增 SliderControl.ItemTemplate、ItemPadding 及可配置左右位置和宽度的 SideContent;修复 Popup 关闭时选项文字、SelectedIndex 与滑块位置不同步;改进批量集合 API。