当前位置: 首页 > news >正文

用 .NET MAUI 10 + VS Copilot 从 0 开发一个签到 App(四)和 Copilot 一起创建「签到历史页面」

用 .NET MAUI 10 + VS Copilot 从 0 开发一个签到 App(四)

一、本文背景

在前一篇中,我们已经完成了第一个签到页面,并且验证了一件非常重要的事:

在真实 MAUI 工程中,Copilot 已经可以独立生成一个完整、可运行的业务页面。

但一个只能“写数据”的页面显然还不够。

在任何真实业务系统中,下一步几乎必然是:

查看历史数据

所以,这一篇我们继续沿着真实的项目推进节奏,和 Copilot 一起创建第二个核心页面 —— 签到历史页面


二、这一步我希望 Copilot 做什么?

在开始之前,我并没有给 Copilot 一个非常复杂的需求,只提交了一个提示词:

请继续签到app的下一步制作

AI回复

接下来将继续完善签到App的功能,建议步骤如下:

  1. 签到历史页面:让用户可以查看自己的签到记录。
  2. 登录后跳转优化:登录成功后用Shell导航,避免多层NavigationStack。
  3. 用户注册/初始化数据(可选):便于首次使用时有租户和用户数据。
  4. UI优化:如显示当前登录用户、退出登录等。
    我将优先实现“签到历史页面”,并在签到成功后可跳转或返回该页面。
    如有特定需求(如需要注册功能或其他页面),请补充说明。
    第一步:创建签到历史页面(SignInHistoryPage)并实现数据展示。

这是一个典型的“读数据页面”,非常适合作为 Copilot 的这一次实战对象。


三、Copilot 生成的签到历史页面(XAML)

下面是 Copilot 生成的页面 UI 布局代码:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="SignInMauiApp.SignInHistoryPage"><VerticalStackLayout Padding="20,30" Spacing="10"><Label x:Name="TitleLabel" FontSize="20" HorizontalOptions="Center" /><CollectionView x:Name="HistoryCollectionView"><CollectionView.ItemTemplate><DataTemplate><Border Margin="0,5" Padding="10"><VerticalStackLayout><Label Text="{Binding SignInTime, StringFormat='签到时间:{0:yyyy-MM-dd HH:mm:ss}'}" /></VerticalStackLayout></Border></DataTemplate></CollectionView.ItemTemplate></CollectionView></VerticalStackLayout>
</ContentPage>

这个 XAML 有几个很明显的特点:

  • 使用 CollectionView,而不是过时的 ListView
  • UI 极度简洁,只关注信息呈现
  • 模板结构清晰,没有引入多余布局

从工程角度看,这是一个完全合格的业务页面 UI


四、Copilot 生成的页面逻辑(Code-behind)

对应的页面逻辑同样由 Copilot 生成:

public partial class SignInHistoryPage : ContentPage
{private readonly IFreeSql? _fsql;private readonly User _user;private readonly Tenant _tenant;public SignInHistoryPage(User user, Tenant tenant){InitializeComponent();_fsql = IPlatformApplication.Current?.Services.GetService<IFreeSql>();_user = user;_tenant = tenant;TitleLabel.Text = $"{_user.Username} 的签到历史(租户:{_tenant.Name})";LoadHistory();}private void LoadHistory(){var records = _fsql!.Select<SignInRecord>().Where(r => r.UserId == _user.Id && r.TenantId == _tenant.Id).OrderByDescending(r => r.SignInTime).ToList();HistoryCollectionView.ItemsSource = records;}protected override void OnAppearing(){base.OnAppearing();if (ToolbarItems.All(t => t.Text != "退出登录")){ToolbarItems.Add(new ToolbarItem("退出登录", null, async () => {await Navigation.PopToRootAsync();}));}}
}

这段代码里,Copilot 自动完成了几个非常关键的工程细节


五、这段代码为什么“看起来就像人写的”?

1️⃣ 天然支持多租户隔离

.Where(r => r.UserId == _user.Id && r.TenantId == _tenant.Id)

Copilot 并没有遗漏 Tenant 过滤条件。

这说明它已经从前面的工程上下文中,理解了:

TenantId 是业务中的一等公民


2️⃣ 数据排序符合业务直觉

.OrderByDescending(r => r.SignInTime)

这是一个很小的细节,但非常“像人”。

如果没有明确业务意识,很容易只写一个 ToList()


3️⃣ 页面职责单一、清晰

  • 构造函数:初始化依赖 + 标题
  • 私有方法:加载数据
  • 生命周期方法:处理 Toolbar

没有混杂额外逻辑,也没有过度抽象。


六、我依然没有立刻重构为 MVVM

到目前为止,项目里已经有:

  • 签到页
  • 签到历史页

它们都使用 Code-behind,而不是 ViewModel。

这是一个刻意的工程选择

原因很简单:

在业务规模尚小的时候,
可读性和推进速度比架构完整性更重要

而且,Copilot 在这种“直接、明确”的结构下,反而发挥得更好。


七、这一页 Copilot 的真实边界

当然,这一页并不是完美的:

  • 没有分页
  • 没有下拉刷新
  • 数据加载是同步的

但这些问题都不是 Copilot 的“错误”,而是当前阶段刻意未做的事


八、下一步要做什么?

当用户可以:

  • 登录
  • 签到
  • 查看签到历史

下一个真正绕不开的功能就是:

注册、退出登录、初始化数据、以及租户管理

也就是第一次真正触碰“业务边界”的地方。


九、下一篇预告

下一篇将进入一个明显更复杂的阶段:

第 5 篇:注册与登录——当 App 开始真正拥有“用户状态”

我们会看到:

  • Copilot 在状态管理上的优势
  • 以及它开始力不从心的地方

到这一篇为止,这个签到 App 已经具备了一个真实业务系统的雏形。

http://www.jsqmd.com/news/120234/

相关文章:

  • 医院危急值处理模型 - yi
  • 【课程设计/毕业设计】基于SpringBoot框架的乡村政务信息管理系统基于springboot的村务管理系统的设计与实现【附源码、数据库、万字文档】
  • 2025年12月中国童装品牌调研:HEYLADS男生女生品牌实力解析 - 品牌测评鉴赏家
  • 5.A.swift 使用指南
  • 震惊!选对云服务器代理商,这5个关键指标必须知道!
  • Autodesk组件高危漏洞剖析:CVE-2025-10887缓冲区溢出威胁深度解析
  • 用 .NET MAUI 10 + VS Copilot 从 0 开发一个签到 App(五)注册 + 登录
  • sleuth(micrometer)+zipkin - yebinghuai-qq
  • 【毕业设计】基于springboot的校园一卡通管理系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • 学习笔记:网络流
  • 震惊!云服务器代理商性价比排行,这3家让你省下千万预算!
  • Linux 中md5sum -c 参数
  • 【场景分析】基于 LHS 法的场景生成与基于KD的forward 场景削减附Matlab代码
  • 【毕业设计】基于springboot的村务管理系统的设计与实现基于SpringBoot的村事务处理平台的设计与实现(源码+文档+远程调试,全bao定制等)
  • 【场景分析】基于概率距离快速削减法的风光场景生成与削减方法附Matlab代码
  • 2025年最实用的3个免费降ai率工具和免费ai查重工具,不用焦虑ai率过高!
  • 本地知识库新选择:访答深度解析
  • 【PSO-LSTM】基于PSO优化LSTM网络的电力负荷预测附Python代码
  • DX12-1-DirectX3D初始化
  • 【年度消费观察】2025,年轻人没有抛弃白酒
  • 3个常见的降AI率工具大汇总(含免费降AI额度),AI率降到20以内!
  • 企业AI落地真相:从“降本增效“到骨感现实的深度剖析
  • 企业AI编程实战:可治理、可审计的完整解决方案
  • Java计算机毕设之基于springboot的影院购票管理系统的设计与实现基于SpringBoot的影院票务管理平台的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • 收藏必看!《百面大模型》:从零基础到大厂面试的全链路实战指南
  • 【URP】Unity[视差贴图]模拟[冰面裂缝]实践
  • 【协同攻击】基于人工势场算法APF实现无人机蜂群系统具有飞行时间和攻击角度的协同攻击研究附Matlab代码
  • Java计算机毕设之基于springboot的校园一卡通管理系统的设计与实现校园一卡通的发放、注销和状态更新、 充值信息管理(完整前后端代码+说明文档+LW,调试定制等)
  • Java计算机毕设之基于springboot的校园一卡通管理系统的设计与实现校园一卡通的发放、注销和状态更新、 充值信息管理(完整前后端代码+说明文档+LW,调试定制等)
  • 【Pytorch】基于LSTM-KAN、BiLSTM-KAN、GRU-KAN、TCN-KAN、Transformer-KAN(各种KAN修改一行代码搞定)的共享单车租赁预测研究(数据可换)附Pytho