news 2026/10/6 12:11:32

SukiUI CalendarDatePicker 日期选择控件:用法指南与主题源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SukiUI CalendarDatePicker 日期选择控件:用法指南与主题源码解析
  • UI组件
  • 桌面应用

【免费下载链接】SukiUI

UI Theme for AvaloniaUI

项目地址:https://gitcode.com/gh_mirrors/su/SukiUI
点击查看免费下载

本篇技术指南围绕 SukiUI(AvaloniaUI 主题框架)内置的CalendarDatePicker日期选择控件展开,介绍其在 SukiUI 主题体系下的基本用法、数据绑定方式、常用属性配置,并结合仓库中 主题实现文件 与 Demo 示例 深入解析其视觉结构与弹出日历的构成原理。读完本文,你将能够在自己的 AvaloniaUI 应用中直接使用并深度定制 SukiUI 风格的日期选择器。

控件简介

CalendarDatePicker是用于选择日期的控件,允许用户通过文本框输入日期,或点击下拉按钮在弹出的日历面板中直观地选取具体日期。它是 SukiUI 主题为 AvaloniaUI 原生CalendarDatePicker控件提供的完整视觉重绘版本,属于日期时间类(datetime)控件家族的一员,与同目录下的Calendar、DatePicker、TimePicker控件共同构成完整的日期时间选择能力。

展示

以下是该控件在 SukiUI 主题下的实际运行效果:

从效果图可以看到,控件主体是一个带有底部细边框的输入框,右侧为日历下拉按钮,点击后弹出带有圆角阴影的日历面板。

基本用法

CalendarDatePicker的用法与 AvaloniaUI 原生控件一致,只需在 XAML 中放置控件并绑定SelectedDate属性即可。原文档给出的最小示例为:

<CalendarDatePicker SelectedDate="{Binding SelectedDateTimeOffset}" />

在 SukiUI 的 Demo 项目 中,该控件被放置于GlassCard+GroupBox组合的 "Date Picker" 分组内,与DatePicker共用同一个SelectedDateTimeOffset绑定源:

<suki:GlassCard> <suki:GroupBox Header="Date Picker"> <StackPanel Spacing="15"> <DatePicker SelectedDate="{Binding SelectedDateTimeOffset}" /> <CalendarDatePicker SelectedDate="{Binding SelectedDateTimeOffset}" /> </StackPanel> </suki:GroupBox> </suki:GlassCard>

绑定类型与双向同步

SelectedDate的类型为DateTimeOffset?(可空)。在 MiscViewModel.cs 中可以看到,Demo 同时维护了DateTime与DateTimeOffset两个属性,并通过源生成器生成的 partial 方法实现双向同步,方便与同页面中的Calendar控件(其SelectedDate为DateTime?)联动:

partial void OnSelectedDateTimeChanged(DateTime value) => SelectedDateTimeOffset = value; partial void OnSelectedDateTimeOffsetChanged(DateTimeOffset value) => SelectedDateTime = value.DateTime;

从 主题模板 的源码看,弹出日历面板中的SelectedDate采用TemplatedParent相对绑定并显式声明Mode=TwoWay,即用户在日历中选择日期后会直接回写到控件的SelectedDate属性,进而通过常规绑定管道通知到 ViewModel:

<Calendar SelectedDate="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedDate, Mode=TwoWay}" />

常用属性配置

结合 主题模板源码 中对PART_Calendar的绑定关系,以下属性均被 SukiUI 主题完整透传到内部日历,可在使用时直接配置:

属性类型说明
SelectedDateDateTimeOffset?当前选中的日期,支持双向绑定,类型为可空DateTimeOffset
DisplayDateDateTime日历打开时默认展示的年月(决定初始视图)
DisplayDateStartDateTime?可选择的日期范围下限,早于该日期的日期不可选
DisplayDateEndDateTime?可选择的日期范围上限,晚于该日期的日期不可选
FirstDayOfWeekDayOfWeek日历视图每周的起始星期
IsTodayHighlightedbool是否在日历中高亮"今天",默认为true
PlaceholderTextstring输入框为空时显示的占位提示文本
UseFloatingPlaceholderbool是否使用浮动占位符(输入后占位文本上浮)

示例:限制用户只能在 2026 年内选择日期,并将周一设为一周的第一天:

<CalendarDatePicker SelectedDate="{Binding SelectedDateTimeOffset}" DisplayDateStart="2026-01-01" DisplayDateEnd="2026-12-31" FirstDayOfWeek="Monday" PlaceholderText="请选择日期" UseFloatingPlaceholder="True" />

主题源码解析:控件长什么样

SukiUI 的CalendarDatePicker主题定义于 SukiUI/Theme/CalendarDatePicker.axaml,其ControlTheme通过Setter预设了如下视觉默认值:

  • Background为Transparent,Height固定为38;
  • BorderThickness为0,0,0,1,即仅保留底部 1px 边框,形成经典的"下划线输入框"外观;
  • FontSize为14,Padding为4,VerticalContentAlignment居中;
  • 边框颜色使用SukiControlBorderBrush,前景色使用SukiText,占位文本颜色使用SukiLowText,均随 SukiUI 明暗主题自动切换。

整体模板结构

模板最外层使用 SukiUI 自带的suki:GlassCard(Classes="Discrete",圆角取SmallCornerRadius,即 8)作为承载容器,内部是一个ColumnDefinitions="*,Auto"的两列网格:

  • 第一列:PART_TextBox,即输入文本框。模板将其背景、边框、圆角、前景色、占位符等属性全部TemplateBinding到控件本身,并透传DataValidationErrors.Errors,因此CalendarDatePicker可以直接参与表单校验,校验错误提示与普通 TextBox 表现一致:
<TextBox Name="PART_TextBox" Classes="NoShadow" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}" PlaceholderForeground="{TemplateBinding PlaceholderForeground}" UseFloatingPlaceholder="{TemplateBinding UseFloatingPlaceholder}" PlaceholderText="{TemplateBinding PlaceholderText}" />
  • 第二列:PART_Button,即日历下拉按钮。按钮本身Background="Transparent"、Focusable="False"、ClipToBounds="False",样式类为CalendarDropDown。其图标并非图片资源,而是纯 XAML 绘制的小日历:顶部一行用SukiPrimaryColor填充作为日历表头,主体显示"今天"的日期数字(绑定sys:DateTime.Today的Day属性),并带有一个 1px 描边的边框。鼠标悬停时(pointerover选择器)表头背景切换为SukiPrimaryColor5,提供轻量的按压反馈。

弹出日历面板

点击下拉按钮后弹出的是PART_Popup(IsLightDismissEnabled="True",点击面板外部自动关闭)。弹出内容为一个Margin="15"的圆角Border,其Background为SukiStrongBackground、BoxShadow为SukiPopupShadow,在明暗主题下都会带有柔和的投影与 14 的圆角;内部再套一层PopupGradientBrush背景的Panel,中央放置PART_Calendar,即真正的日历本体。日历本体及其日按钮、表头的视觉样式由 SukiUI/Theme/Calendar/Calendar.axaml 及同目录下的CalendarItem.axaml、CalendarDayButton.axaml、CalendarButton.axaml共同提供,形成统一的视觉语言。

焦点态

模板还通过样式选择器定义了焦点样式,输入框获得焦点时底部边框切换为高亮色:

<Style Selector="^:focus /template/ TextBox#PART_TextBox"> <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}" /> </Style>

主题如何自动生效

SukiUI 通过 SukiUI/Theme/Index.axaml 中的MergedDictionaries一次性引入全部控件主题,其中就包括:

<ResourceInclude Source="avares://sukiUI/Theme/CalendarDatePicker.axaml" /> <ResourceInclude Source="avares://sukiUI/Theme/Calendar/Calendar.axaml" /> <ResourceInclude Source="avares://sukiUI/Theme/Calendar/CalendarButton.axaml" /> <ResourceInclude Source="avares://sukiUI/Theme/Calendar/CalendarDayButton.axaml" /> <ResourceInclude Source="avares://sukiUI/Theme/Calendar/CalendarItem.axaml" />

因此,只要应用已加载 SukiUI 主题(在App.axaml中引用SukiUI.Theme或SukiTheme资源),CalendarDatePicker无需额外引入样式即可自动呈现 SukiUI 风格。

更多使用场景

除了 Misc 示例页,CalendarDatePicker还用于 DataGridView.axaml 的编辑场景中,作为数据表格某列的可编辑日期输入控件:

<CalendarDatePicker SelectedDate="{Binding Updated}" />

这印证了该控件可无缝嵌入表格、表单等复杂容器,配合DataValidationErrors.Errors透传能力完成校验闭环。若需要查看完整可运行示例,可参考 Demo 项目中的 MiscView.axaml(与Calendar、DatePicker、TimePicker同屏对比展示),控件的中文说明文档位于 calendardatepicker.md。

  • UI组件
  • 桌面应用

【免费下载链接】SukiUI

UI Theme for AvaloniaUI

项目地址:https://gitcode.com/gh_mirrors/su/SukiUI
点击查看免费下载
上一篇:PushDeer推送证书配置:终极解决iOS和Android推送难题
下一篇:GHelper 完整指南:用单个 exe 在 5 分钟内涵养一台华硕游戏本

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 12:09:43

字母大小写全排列:递归走完一条路,为什么要删掉最后一个字符?

力扣784&#xff1a;字母大小写全排列给一个只含英文字母和数字的字符串。每个字母可以保留或切换大小写&#xff0c;数字不变&#xff0c;返回所有结果&#xff0c;顺序不限。长度为1至12。 我原来的代码用 StringBuffer path 记录走过的字符&#xff0c;用递归处理下一位。实…

作者头像 李华
网站建设 2026/10/6 12:05:41

SO-DIMM物理兼容性指南:DDR3与DDR4不可互插的四大铁律

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 12:05:22

DeepSeek大模型智慧办公落地指南:从部署到避坑的完整工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 12:04:44

Allegro模块复用实战:Place Replicate与Group五分钟高效布局布线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 12:04:10

TPU 3D打印总失败?Simplify3D切片参数调优全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 12:04:09

FB_LLC谐振变换器死区时间与ZVS量化设计指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华