mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
4300 words
12 minutes
Heyiwei2 说明文档
2026-05-31

摘要#

Heyiwei2 是一个基于 WinUI 3 与 C++/WinRT 的学生宿舍水费管理系统,核心目标是实现宿舍信息管理、学生管理、用水记录管理与水费计算,并提供本地 JSON 数据持久化。该项目为高校宿舍水费管理提供了一套可视化、可扩展的解决方案,既完成了宿舍与学生信息管理,也实现了用水记录与阶梯计费。通过 WinUI 3 的界面与 C++/WinRT 的数据绑定,项目具备较好的用户体验与工程实现价值。

关键词:宿舍水费管理,WinUI 3,C++/WinRT,数据持久化

Abstract#

Heyiwei2 is a student dormitory water fee management system built on WinUI 3 and C++/WinRT, aiming to refactor the original command-line version Heyiwei into a modern Windows desktop application. The core objectives of the project are to implement dormitory information management, student management, water usage record management, and water fee calculation, while providing local JSON data persistence. The project offers a visual and extensible solution for dormitory water fee management in universities, enabling not only the management of dormitory and student information but also the handling of water usage records and tiered billing. By leveraging the WinUI 3 interface and C++/WinRT data binding, the project delivers a strong user experience and engineering value.

Key words: dormitory water fee management, WinUI 3, C++/WinRT, data persistence, input validation, module separation

一、项目概述#

1.1 项目背景#

高校后勤管理中,学生宿舍水费管理是一项日常工作。传统的人工抄表和纸质记录方式效率低下,数据容易丢失,不便于统计查询。本课题旨在开发一套现代化的宿舍水费管理系统,实现宿舍信息、学生入住、用水记录的信息化管理,提高管理效率。

1.2 项目目标#

  • 提供直观的图形化操作界面
  • 实现宿舍信息的增删改查
  • 实现学生入住管理(添加、编辑、删除)
  • 实现用水记录的登记与维护
  • 自动计算阶梯水费
  • 支持数据持久化存储与加载

1.3 技术选型#

技术项选择方案说明
编程语言C++17现代C++标准,支持协程、智能指针等特性
UI框架WinUI 3微软最新原生UI框架,提供Fluent Design视觉效果
语言投影C++/WinRT以标准C++调用WinRT API,无需额外的托管运行时
数据序列化cereal轻量级C++序列化库,支持JSON格式输出
开发环境Visual Studio 2026完整IDE支持,集成XAML设计器与调试工具
运行平台Windows 10/11原生桌面应用,无需额外运行时

选型理由:WinUI 3是微软最新的原生UI框架,提供现代化的Fluent Design界面风格,支持亚克力材质、圆角控件、流畅动画等视觉效果。C++/WinRT编译为原生代码,启动速度快、内存占用低、性能优异。相较于传统的Qt Widgets或MFC,WinUI 3在界面美观度和用户体验上有显著优势。

1.4 项目分工#

组员说明
陈东扬宿舍列表页面排版布局、宿舍增加删减按钮设计、输入正确性检验、本地数据储存
张顺理架构设计、宿舍管理页面排版布局、编辑按钮事件编写、数据结构设计、数据与UI间的动态绑定
竹永琪工具类编写:计算水费信息、信息检验、获取当前年月日;主管理逻辑编写:添加删除宿舍、添加删除学生
汪泽群宿舍管理逻辑编写、添加删除学生、添加删除水费记录;页面导航功能编写
吴溢轩水费管理逻辑编写:添加删除水费记录;数据保存转换编写:转换 winrt 与普通 C++ 类型,序列化与反序列化数据

二、需求分析#

2.1 功能需求#

2.1.1 宿舍管理模块#

  • 添加宿舍:选择区域、楼栋、楼层,输入房间号
  • 编辑宿舍基本信息:修改区域、楼栋、楼层、房间号
  • 删除宿舍
  • 列表展示所有宿舍
  • 点击宿舍查看详细信息

2.1.2 学生管理模块#

  • 添加学生(姓名、学号)到指定宿舍
  • 编辑学生信息
  • 删除学生
  • 学号唯一性检查(全局去重)
  • 学号格式验证(10位数字)

2.1.3 用水记录管理模块#

  • 添加用水记录(年月、用水量)
  • 编辑用水记录
  • 删除用水记录
  • 自动计算阶梯水费
  • 用水记录按年月排序
  • 宿舍起始日期变更时自动补全月份记录

2.1.4 数据持久化模块#

  • 程序启动时自动从JSON文件加载数据
  • 每次数据变更后自动保存
  • JSON格式存储,结构清晰可读

2.1.5 系统设置模块#

  • 深色/浅色主题切换
  • 主题偏好记忆(下次启动自动应用)

2.2 非功能需求#

  • 界面响应流畅,操作反馈及时
  • 数据自动保存,避免意外退出导致数据丢失
  • 界面布局自适应窗口大小
  • 错误提示友好明确,避免程序崩溃
  • 编译为原生x64代码,充分利用硬件性能

三、系统设计#

3.1 系统架构#

本系统采用基于MVC思想的分层架构,结合实际开发需求,设计为MVM(Model-View-Manager)模式:

各层职责:

  • **View层:**负责界面展示和用户交互,通过IObservableVector数据绑定与Manager层联动。不对数据做直接修改,所有操作通过Manager层完成。
  • **Manager层:**系统的核心枢纽。MainManager持有全局数据集合dorms(IObservableVector),提供所有业务操作的统一入口。内部委托DormManager处理单宿舍的学生和用水记录操作,委托RecordManager处理用水记录的年月索引管理。
  • **Model层:**定义数据结构。所有Model类均实现INotifyPropertyChanged接口,属性变更时可自动通知UI刷新。
  • **持久化层:**负责数据的序列化与反序列化。通过StdModelsConverter在WinRT对象和普通C++结构体之间转换,利用cereal库实现JSON格式的读写。

3.2 数据绑定机制#

本项目采用IObservableVector + INotifyPropertyChanged双层通知机制:
集合层面:MainManager持有IObservableVector,各页面通过绑定该集合获取数据。当集合发生Append、RemoveAt、SetAt等操作时,自动触发VectorChanged事件,ListView等列表控件自动刷新。
属性层面:所有Model类(Dorm、DormInfo、Student、WaterRecord)均实现INotifyPropertyChanged接口。当对象的某个属性被修改时,触发PropertyChanged事件,绑定到该属性的控件自动更新,无需整体替换对象。

3.3 核心数据结构#

DormInfo(宿舍基本信息)#

属性类型说明
RegionInt32区域编号
BuildingNumberInt32楼栋号
FloorInt32楼层
RoomNumberInt32房间号
StartDateYearInt32入住起始年份
StartDateMonthInt32入住起始月份

Dorm(宿舍)#

属性类型说明
DormIdString唯一标识(由区域-楼栋-楼层-房间号拼接生成)
InfoDormInfo基本信息
StudentsIObservableVector入住学生列表
RecordsIObservableVector用水记录列表

WaterRecord(用水记录)#

属性类型说明
YearInt32年份
MonthInt32月份
UsageDouble用水量(吨)
CostDouble水费(元),由Usage自动计算
HasPaidBoolean是否已缴费

Student(学生)#

属性类型说明
NameString姓名
StudentIdString学号(10位数字)

3.4 水费计算#

采用广州市居民阶梯水价标准:

阶梯月用水量单价
第一阶梯≤26吨2.93元/吨
第二阶梯27-34吨4.40元/吨
第三阶梯>34吨7.87元/吨

四、详细实现#

4.1 主界面(MainPage)#

主界面采用NavigationView控件实现侧边导航布局:

  • 顶部为应用标题和深色模式切换按钮
  • 左侧为导航菜单(宿舍列表、设置等)
  • 右侧为Frame控件承载子页面,实现页面间导航

4.2 宿舍列表页(DormListPage)#

功能:

  • 展示所有宿舍信息列表
  • 提供”添加宿舍”按钮
  • 点击宿舍行查看/管理详细信息
  • 列表项绑定Dorm对象,显示DormId、区域、楼栋等信息

4.3 宿舍管理表单(DormManageForm)#

功能:

  • 显示宿舍详细信息(区域、楼栋、楼层、房间号、入住日期)
  • 管理入住学生列表(添加、编辑、删除)
  • 管理用水记录列表(添加、编辑、删除)
  • 编辑宿舍基本信息(通过ContentDialog弹窗)
  • 关闭按钮触发回调,通知父页面移除本表单

关键技术:

  • 表单通过DataContext绑定到Dorm对象
  • 编辑操作通过ContentDialog弹出EditDormForm、EditStudentForm、EditRecordForm
  • 异步操作使用C++20协程(IAsyncAction、co_await)
  • 关闭回调采用std::function实现,避免循环引用

4.4 编辑表单控件#

EditDormForm:#

  • 区域、楼栋、楼层使用ComboBox选择
  • 房间号使用TextBox输入
  • 起始年月使用ComboBox选择,年份和月份联动(选择年份后月份列表自动更新)
  • 使用标志位monthSelectionInitialize避免页面初始化时误触发月份刷新

EditStudentForm:#

  • 姓名和学号使用TextBox输入 EditRecordForm:
  • 年份、月份使用ComboBox选择
  • 用水量使用TextBox输入
  • 编辑模式下锁定年月不可修改

4.5 数据验证#

学生验证:

  • 姓名不能为空
  • 学号不能为空
  • 学号长度必须为10位
  • 学号必须全为数字字符
  • 全局学号唯一性检查(遍历所有宿舍)

用水记录验证:

  • 年份不低于2026年
  • 月份在1-12之间
  • 用水量不能为负数
  • 用水量上限检查(不超过30000吨,含友好提示)

宿舍验证:

  • 房间号格式检查
  • 宿舍ID唯一性检查

4.6 数据持久化#

序列化流程

反序列化流程

4.7 深色模式#

通过ElementTheme枚举实现深色/浅色主题切换:

  • 设置页面提供ToggleSwitch开关
  • 切换时修改XamlRoot().Content()的RequestedTheme属性
  • 使用ApplicationData::LocalSettings持久化用户偏好
  • 应用启动时自动读取偏好并应用

4.8 月份补全逻辑#

当修改宿舍入住起始日期时,系统自动补全对应月份的用水记录:

  • 若有已有记录,从最后一条记录的上一个月开始补
  • 若无记录,从当前年月开始补
  • 仅当新起始日期早于旧起始日期时才执行补全
  • 补全年份和月份保持连续,不重复生成已有记录

五、关键技术难点与解决方案#

5.1 C++/WinRT数据绑定的线程问题#

问题:在后台线程修改数据时,INotifyPropertyChanged的PropertyChanged事件必须在UI线程触发,否则会抛出RPC_E_WRONG_THREAD异常。

解决方案:

  • 确保所有Model对象的属性修改均在UI线程执行
  • 使用DispatcherQueue在需要时将操作调度到UI线程
  • 数据加载和保存操作在UI线程完成,避免跨线程数据操作

5.2 多页面数据同步#

问题:DormListPage和DormManageForm可能同时引用同一个Dorm对象,一处修改需要多处感知。

解决方案:

  • 所有数据由MainManager统一持有IObservableVector集合
  • 各页面绑定同一个集合引用
  • 修改后通过SetAt触发VectorChanged事件,所有绑定处自动刷新
  • 属性级变更通过INotifyPropertyChanged自动通知

5.3 序列化与UI绑定的兼容#

问题:加载数据时如果直接替换整个集合引用,会导致UI绑定断开。

解决方案:

  • 加载数据后不替换集合引用
  • 使用Clear()清空原有数据
  • 使用Append()逐个添加新数据
  • 保持IObservableVector引用不变,UI绑定持续有效

5.4 编译资源不足#

问题:项目包含大量WinRT头文件,预编译头体积可达数GB,编译时虚拟内存不足导致失败。

解决方案:

  • 增大Windows虚拟内存(页面文件)至16GB以上
  • 使用x64编译配置(x86有4GB内存限制)
  • 关闭不必要的后台程序释放内存
  • 减少pch.h中不必要的头文件包含

5.5 月份补全年份与循环变量类型安全#

问题:月份补全逻辑涉及多年跨度的循环,使用size_t(无符号类型)作为循环变量时,递减到0后会溢出变成极大值,导致死循环或无限追加。

解决方案:使用有符号整数类型(int或int32_t)作为循环变量,确保递减到边界值时循环正确终止。

六、测试与运行#

6.1 测试环境#

项目配置
操作系统Windows 10/11
编译环境Visual Studio 2026
编译配置x64 Debug/Release
运行时WinUI 3 + C++/WinRT
依赖库cereal(header-only)

6.2 功能测试#

测试项测试步骤预期结果实际结果
添加宿舍点击添加按钮,填写信息,确认列表中显示新宿舍,数据保存通过
编辑宿舍信息点击编辑按钮,修改信息,确认信息更新,列表刷新通过
删除宿舍点击删除按钮,确认列表中移除,数据保存通过
添加学生在宿舍详情中点击添加学生,填写信息学生列表更新,全局学号唯一性检查通过通过
编辑学生点击学生编辑按钮,修改信息学生信息更新通过
删除学生点击删除按钮,确认学生从列表中移除通过
添加用水记录点击添加记录,填写年月和用量记录显示,水费自动计算通过
编辑用水记录点击记录编辑,修改用量水费重新计算,记录更新通过
删除用水记录点击删除按钮,确认记录从列表中移除通过
数据持久化关闭程序后重新打开所有数据完整保留通过
深色模式切换在设置中切换深色模式开关界面实时切换,重启后保持通过
月份补全修改宿舍起始日期为更早时间自动生成对应月份的用水记录通过
数据验证输入非法数据(空学号、负数用水量等)显示友好错误提示通过

6.3 运行截图#

七、总结与展望#

7.1 项目总结#

本项目基于WinUI 3 + C++/WinRT技术栈,成功实现了一套功能完整、界面现代的学生宿舍水费管理系统。系统采用MVM分层架构,通过IObservableVector和INotifyPropertyChanged实现响应式UI数据绑定,具备宿舍管理、学生管理、用水记录管理、阶梯水费自动计算、数据JSON序列化持久化、深色模式切换等完整功能。

在开发过程中,深入研究了C++/WinRT的运行时特性与线程模型、WinUI 3的数据绑定机制、现代C++的协程与智能指针、软件分层架构设计等核心技术。解决了多线程UI更新、跨页面数据同步、编译资源优化、序列化与UI绑定兼容等多个工程实际问题。

7.2 技术收获#

通过本次课程设计,加深了对以下知识的理解:

  • C++/WinRT的COM接口机制与对象生命周期管理
  • WinUI 3的XAML数据绑定与MV*架构模式
  • 现代C++的协程(co_await、IAsyncAction)在异步UI操作中的应用
  • JSON序列化库cereal在C++项目中的集成
  • 桌面应用的分层架构设计与模块解耦
  • 编译优化与调试技巧

7.3 未来改进方向#

  • 引入图表组件,实现用水趋势的可视化展示
  • 支持数据导出为Excel格式
  • 添加管理员登录与权限管理功能
  • 部署到局域网环境,支持多客户端同时访问
  • 增加单元测试,提高代码质量保障
  • 优化数据加载性能,支持更大规模数据量  

参考文献#

[1] Microsoft Docs. WinUI 3 Documentation. https://learn.microsoft.com/en-us/windows/apps/winui/

[2] Microsoft Docs. C++/WinRT Documentation. https://learn.microsoft.com/zh-cn/windows/uwp/cpp-and-winrt-apis/

[3] cereal. A C++11 library for serialization. https://github.com/USCiLab/cereal

[4] Microsoft Docs. IObservableVector Interface. https://learn.microsoft.com/en-us/uwp/api/windows.foundation.collections.iobservablevector-1

[5] Microsoft Docs. INotifyPropertyChanged Interface. https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.data.inotifypropertychanged

Share

If this article helped you, please share it with others!

Heyiwei2 说明文档
https://blog.vista233.top/posts/cppproject-design2-document/
Author
forer4433
Published at
2026-05-31
License
CC BY-NC-SA 4.0

Some information may be outdated

关于本网站
即时欣赏:osu!
Cover
Sample Song
Sample Artist
Cover
Sample Song
Sample Artist
0:00 / 0:00