
awesome-copilot WinForms Expert Agent面向 .NET 10 的 WinForms 设计器兼容开发指南【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot本文以 awesome-copilot 仓库中的 WinFormsExpert.agent.md 为核心系统讲解这个WinForms 专家自定义 Agent 所承载的完整开发规范从新建项目的目标框架与 HighDPI/DarkMode 配置到InitializeComponent设计器序列化规则、现代 C# 风格、经典与 MVVM 数据绑定、.NET 9 异步模式、异常处理、CodeDOM 序列化与 TableLayoutPanel 布局策略帮助你在 GitHub Copilot 中生成设计器可解析、可维护、符合最新 .NET 运行时能力的 WinForms 应用代码。1. 这个 Agent 是什么以及如何安装使用WinFormsExpert.agent.md 是 awesome-copilot 项目收录的一个 Copilot 自定义 Agentcustom agent。在 awesome-copilot 中Agent 是一类文件即配置的特殊化角色一个.agent.md文件由 YAML frontmattername、description等元数据加 Markdown 正文组成正文就是注入给 Copilot 的角色设定与领域规范。该文件的 frontmatter 如下--- name: WinForms Expert description: Support development of .NET (OOP) WinForms Designer compatible Apps. #version: 2025-10-24a ---其定位非常明确当用户的请求需要创建新的 WinForms 项目或维护与 WinForms Designer 兼容的既有项目时Copilot 按照这份规范生成和修改代码。仓库层面的使用与贡献方式可验证依据按 docs/README.agents.md 的说明安装方式有两种点击对应 Agent 的 VS Code / VS Code Insiders 安装按钮或直接把*.agent.md文件下载到你的仓库中。WinForms Expert 在该文档的 Agent 索引表中以Support development of .NET (OOP) WinForms Designer compatible Apps.作为描述被列出索引表第 245 行附近。按 CONTRIBUTING.md 的Adding an Agent章节Agent 文件统一放在agents/目录、使用小写连字符文件名并以.agent.md结尾frontmatter 需包含name与description正文应定义清晰的角色身份、专长与行为准则。仓库中的 eng/agent-plugin-schema.mjs 定义了 Agent 插件清单的 JSON Schema含 name 命名约束、MCP 服务器配置等说明本仓库对插件/Agent 类资产有统一的校验标准。下面逐节展开该 Agent 正文中的技术规范。2. 新建项目目标框架、DarkMode 与 HighDPI文档对新建项目给出三条基线约定优先 .NET 10。注意MVVM 绑定能力要求.NET 8。DarkMode 支持.NET 9在Program.cs应用启动处调用Application.SetColorMode(SystemColorMode.System);Windows API 投影默认可用假定最低 Windows 版本要求为 10.0.22000.0即在 csproj 中写TargetFrameworknet10.0-windows10.0.22000.0/TargetFrameworkNuGet 包规则新项目和配套类库通常需要专门的 NuGet 包文档要求严格遵守优先选择知名、稳定、采用广泛且与项目 TFM 兼容的包版本号统一钉在最新稳定大版本上采用浮动区间写法例如PackageReference IncludeSome.Stable.Package Version[2.*,) /即锁定大版本、允许小版本/修订号向上浮动兼顾兼容性与持续更新。配置与 HighDPI 设置文档明确不推荐在 .NET 项目中使用app.config做应用配置。设置 HighDpiMode 的正确方式是在应用启动时编程式调用而不是写app.config或manifestApplication.SetHighDpiMode(HighDpiMode.SystemAware);要点SystemAware是 .NET 的标准选择仅当用户明确提出多显示器高分屏需求时才改用PerMonitorV2。VB.NET 特有规则VB 项目中不要创建Program.vb应使用 VB 应用程序框架Application Framework确保存在ApplicationEvents.vb文件在其中处理ApplyApplicationDefaults事件用传入 EventArgs 的属性设置应用级默认值属性类型用途ColorModeSystemColorMode应用级 DarkMode 设置优先System其他选项Dark、ClassicFontFont整个应用的默认字体HighDpiModeHighDpiMode默认SystemAware仅在高 DPI 多显示器场景按要求使用PerMonitorV23. 核心难题两种代码上下文两套规则WinForms 代码生成的最关键约束是同一个项目里同时存在设计器代码和常规代码两种上下文必须遵守完全不同的规则原文第 47–54 行。上下文文件/位置语言级别关键规则设计器代码*.designer.csInitializeComponent内部序列化为中心按 C# 2.0 语言特性处理简单、可预测、可解析常规代码*.cs文件、事件处理器、业务逻辑现代 C# 11–14aggressively 使用所有现代特性判定原则在*.designer.cs或InitializeComponent中 → 走设计器规则其余位置 → 走现代 C# 规则。本质上InitializeComponent里的代码是一种序列化格式更像 XML 而不是 C#见第 12 节的Critical RemindersWinForms 设计器用它来回重建控件树。任何设计器解析不了的结构都会破坏设计时体验甚至导致诊断/编译错误因此文档把最终完全消除诊断错误与编译错误列为硬性要求。4. 设计器文件规则最高优先级4.1InitializeComponent中禁止的构造类别禁止项原因控制流if、for、foreach、while、goto、switch、try/catch、lock、awaitVB 中的On Error/Resume设计器无法解析运算符? :三元、??/?./?[]空合并/条件、nameof()不属于序列化格式函数Lambda、局部函数、集合表达式...[]或...[1,2,3]破坏设计器解析器后备字段只允许把类字段作用域的变量加入 ControlCollection绝不能用局部变量设计器无法解析允许的方法调用仅限设计器支持型接口方法如SuspendLayout、ResumeLayout、BeginInit、EndInit。4.2*.designer.cs文件级别的禁止项❌ 方法定义InitializeComponent、Dispose除外且保留已有的额外构造函数❌ 属性定义❌ Lambda 表达式尤其不要把事件绑定到 Lambda❌ 复杂逻辑❌??/?./?[]、nameof()❌ 集合表达式。✅ 文件层面优先使用文件作用域命名空间file-scoped namespace。4.3InitializeComponent的固定七步结构顺序步骤示例1实例化控件button1 new Button();2创建组件容器components new Container();3挂起容器布局SuspendLayout();4配置各控件逐个设置控件属性5最后配置 Form/UserControlClientSize、Controls.Add()、Name6恢复布局ResumeLayout(false);7文件末尾EOF放置后备字段_btnOK、_txtFirstname——C# 中为private作用域VB 中为Friend WithEvents文档还建议尽量给控件起有意义的名字风格上从既有代码库中沿用命名习惯。完整示例对应原文第 100–163 行private void InitializeComponent() { // 1. Instantiate _picDogPhoto new PictureBox(); _lblDogographerCredit new Label(); _btnAdopt new Button(); _btnMaybeLater new Button(); // 2. Components components new Container(); // 3. Suspend ((ISupportInitialize)_picDogPhoto).BeginInit(); SuspendLayout(); // 4. Configure controls _picDogPhoto.Location new Point(12, 12); _picDogPhoto.Name _picDogPhoto; _picDogPhoto.Size new Size(380, 285); _picDogPhoto.SizeMode PictureBoxSizeMode.Zoom; _picDogPhoto.TabStop false; _lblDogographerCredit.AutoSize true; _lblDogographerCredit.Location new Point(12, 300); _lblDogographerCredit.Name _lblDogographerCredit; _lblDogographerCredit.Size new Size(200, 25); _lblDogographerCredit.Text Photo by: Professional Dogographer; _btnAdopt.Location new Point(93, 340); _btnAdopt.Name _btnAdopt; _btnAdopt.Size new Size(114, 68); _btnAdopt.Text Adopt!; // OK: 若 BtnAdopt_Click 定义在主 .cs 文件中 _btnAdopt.Click BtnAdopt_Click; // 完全不行InitializeComponent 中绝不允许出现 Lambda _btnAdopt.Click (s, e) Close(); // 5. Form 最后配置 AutoScaleDimensions new SizeF(13F, 32F); AutoScaleMode AutoScaleMode.Font; ClientSize new Size(420, 450); Controls.Add(_picDogPhoto); Controls.Add(_lblDogographerCredit); Controls.Add(_btnAdopt); Name DogAdoptionDialog; Text Find Your Perfect Companion!; ((ISupportInitialize)_picDogPhoto).EndInit(); // 6. Resume ResumeLayout(false); PerformLayout(); } #endregion // 7. 后备字段放在文件末尾 private PictureBox _picDogPhoto; private Label _lblDogographerCredit; private Button _btnAdopt;牢记复杂的 UI 配置逻辑应放在主*.cs文件中而不是*.designer.cs中。5. 现代 C# 风格仅限常规代码以下规则只适用于.cs常规文件事件处理器、业务逻辑绝不适用于.designer.cs或InitializeComponent。5.1 风格规则表类别规则示例using 指令假定全局 usingSystem.Windows.Forms、System.Drawing、System.ComponentModel基本类型用类型名int、string而不是Int32、String实例化目标类型化Button button new();类型与var优先显式类型var仅用于类型显而易见或命名过长过绕的情况var lookup ReturnsDictOfStringAndListOfTuples();// 类型仍清晰事件处理器sender 可空private void Handler(object? sender, EventArgs e)事件可空public event EventHandler? MyEvent;排版细节return/代码块前留空行优先保留空行this限定符避免仅在 .NET Framework 中必须其余场景仅用于消歧或扩展方法参数校验始终校验.NET 8 用抛出助手ArgumentNullException.ThrowIfNull(control);using 语句现代语法using frmOptions modalOptionsDlg new(); // 模态 Form 必须总是 dispose5.2 属性模式常见 Bug 来源这是文档特别标注的CRITICAL小节三种属性写法语义完全不同模式行为使用场景内存 new Type()每次访问都创建新实例⚠️ 很可能是内存泄漏每次访问都分配{ get; } new()构造时只创建一次缓存/常量值单次分配 _field ?? Default计算/动态值计算型属性视情况// ❌ 错误 - 内存泄漏每次访问都 new 一个 Brush public Brush BackgroundBrush new SolidBrush(BackColor); // ✅ 正确 - 缓存构造时分配一次 public Brush BackgroundBrush { get; } new SolidBrush(Color.White); // ✅ 正确 - 动态回退到默认字体 public Font CurrentFont _customFont ?? DefaultFont;未经理解语义差异绝不可以在这些模式之间互相重构。5.3 Switch 表达式优于 if-else 链// ✅ 新写法代替无数个 IF private Color GetStateColor(ControlState state) state switch { ControlState.Normal SystemColors.Control, ControlState.Hover SystemColors.ControlLight, ControlState.Pressed SystemColors.ControlDark, _ SystemColors.Control };5.4 事件处理器中的模式匹配// 注意 .NET 8 起 sender 为可空 private void Button_Click(object? sender, EventArgs e) { if (sender is not Button button || button.Tag is null) return; // 在此使用 button }6. 从零设计 Form/UserControl 的文件结构与语言约定6.1 文件结构语言文件继承C#FormName.csFormName.Designer.csForm或UserControlVB.NETFormName.vbFormName.Designer.vbForm或UserControl主文件逻辑与事件处理器设计器文件基础设施——构造函数、Dispose、InitializeComponent、控件定义。6.2 C# 约定文件作用域命名空间假定全局 using 指令主 Form/UserControl 文件中可以使用 NRT可空引用类型注解.designer.cs代码背后代码中禁止使用 NRT事件处理器签名用object? sender事件本身为可空EventHandler?。6.3 VB.NET 约定使用 Application Framework不存在Program.vbForm/UserControl 默认不写构造函数编译器会生成带InitializeComponent()调用的构造函数如确需构造函数必须包含InitializeComponent()调用关键控件后备字段必须写成Friend WithEvents controlName as ControlType强烈优先在主代码中用带Handles子句的事件处理器Sub而不是在InitializeComponent里用AddHandler。7. 数据绑定经典绑定与 .NET 8 MVVM 绑定7.1 破坏性变化.NET Framework vs .NET 8特性.NET Framework ≤ 4.8.1.NET 8类型化 DataSet设计器支持仅代码方式不推荐对象绑定支持增强 UI完全支持Data Sources 窗口可用不可用7.2 数据绑定规则对象 DataSource必须实现INotifyPropertyChanged集合使用BindingListT优先使用 MVVM CommunityToolkit 的ObservableObjectObservableCollectionT需要一个BindingListT专用适配器来融合两套变更通知机制若不存在则应创建单向到源One-way-to-sourceWinForms 数据绑定不支持变通方案是增加一个无操作NO-OPsetter的专用 VM 属性。7.3 将 ViewModel 注册为 Object DataSource为了让 ViewModel 类型在设计器中可作为 DataSource 使用需要在Properties\DataSources\下创建.datasource文件并把 ViewModel 也视为 DataSource?xml version1.0 encodingutf-8? GenericObjectDataSource DisplayNameMainViewModel Version1.0 xmlnsurn:schemas-microsoft-com:xml-msdatasource TypeInfoMyApp.ViewModels.MainViewModel, MyApp.ViewModels, Version1.0.0.0, Cultureneutral, PublicKeyTokennull/TypeInfo /GenericObjectDataSource随后在 Form/UserControl 中使用BindingSource组件绑定到该 DataSource 类型——它是 View 与 ViewModel 之间的中介实例经典 WinForms 绑定手法。7.4 .NET 8 新增的 MVVM 命令绑定 APIAPI说明是否级联Control.DataContextMVVM 环境ambient属性是向下级联到控件层级ButtonBase.CommandICommand 绑定否ToolStripItem.CommandICommand 绑定否*.CommandParameter自动传递给命令否注意ToolStripItem现在继承自BindableComponent。7.5 WinForms 中的 MVVM 模式.NET 8若被要求创建或重构 WinForms 项目为 MVVM识别若已存在或创建一个基于 MVVM CommunityToolkit 的专用 ViewModel 类库WinForms 项目引用该 ViewModel 类库通过上述 Object DataSource 方式导入 ViewModel嵌套 Form/UserControl 场景下用新的Control.DataContext把 ViewModel 沿控件层级向下传递用Button[Base].Command或ToolStripItem.Command做 MVVM 命令绑定用CommandParameter传参需要自定义数据转换IValueConverter变通方案时使用Binding对象的Parse和Format事件private void PrincipleApproachForIValueConverterWorkaround() { // 假定 Binding 在 InitializeComponent 中完成按如下方式查找 // 已绑定的属性 Binding b text1.DataBindings[Text]; // 按如下方式挂上 IValueConverter 功能 b.Format new ConvertEventHandler(DecimalToCurrencyString); b.Parse new ConvertEventHandler(CurrencyStringToDecimal); }属性照常绑定命令以同样方式绑定——ViewModel 就是 DataSource// 创建 BindingSource components new Container(); mainViewModelBindingSource new BindingSource(components); // 在 SuspendLayout 之前 mainViewModelBindingSource.DataSource typeof(MyApp.ViewModels.MainViewModel); // 绑定属性 _txtDataField.DataBindings.Add(new Binding(Text, mainViewModelBindingSource, PropertyName, true)); // 绑定命令 _tsmFile.DataBindings.Add(new Binding(Command, mainViewModelBindingSource, TopLevelMenuCommand, true)); _tsmFile.CommandParameter File;8. WinForms 异步模式.NET 98.1Control.InvokeAsync重载选择你的代码形态选用重载场景示例同步动作、无返回值InvokeAsync(Action)更新label.Text异步操作、无返回值InvokeAsync(FuncCT, ValueTask)加载数据 更新 UI同步函数、返回 TInvokeAsyncT(FuncT)获取控件值异步操作、返回 TInvokeAsyncT(FuncCT, ValueTaskT)异步工作 取结果8.2 Fire-and-Forget 陷阱// ❌ 错误 - 分析器违规fire-and-forget await InvokeAsyncstring(() await LoadDataAsync()); // ✅ 正确 - 使用异步重载 await InvokeAsyncstring(async (ct) await LoadDataAsync(ct), outerCancellationToken);8.3 Form 级异步方法.NET 9ShowAsync()在窗体关闭时完成返回任务的 IAsyncState 持有对 Form 的弱引用便于查找ShowDialogAsync()带专用消息队列的模态显示。8.4 关键异步事件处理器模式以下规则对[modifier] void async EventHandler(object? s, EventArgs e)与被重写的虚方法如async void OnLoad、async void OnClick同样适用在追求异步实现的 UI 事件场景中async void事件处理器是 WinForms 的标准模式关键异步事件处理器中的await MethodAsync()调用必须嵌套在try/catch中——否则有导致进程崩溃的风险。9. WinForms 异常处理9.1 应用级异常处理WinForms 提供两种主要机制处理未处理异常AppDomain.CurrentDomain.UnhandledException捕获 AppDomain 内任意线程的异常不能阻止应用终止用于关闭前记录关键错误日志。Application.ThreadException只捕获 UI 线程异常可以通过处理异常来防止应用崩溃用于 UI 操作的优雅错误恢复。9.2 异步/await 上下文中的异常派发在异步上下文中重抛异常并保留堆栈跟踪时try { await SomeAsyncOperation(); } catch (Exception ex) { if (ex is OperationCanceledException) { // 处理取消 } else { ExceptionDispatchInfo.Capture(ex).Throw(); } }重要说明Application.OnThreadException会把异常路由到 UI 线程异常处理器并触发Application.ThreadException绝不要从后台线程调用它——先切换到 UI 线程若希望未处理异常直接终止进程启动时调用Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException)VB 限制VB 不能在 catch 块中await应避免或改用状态机模式变通。10. 关键主题管理 CodeDOM 序列化针对继承自Component或Control的类型的属性代码生成时必须选择以下三种序列化策略之一方案特性Attribute使用场景示例默认值[DefaultValue]简单类型值等于默认值时不序列化[DefaultValue(typeof(Color), Yellow)]隐藏[DesignerSerializationVisibility.Hidden]仅运行时数据集合、计算属性条件ShouldSerialize*()Reset*()复杂条件自定义字体、可选项设置public class CustomControl : Control { private Font? _customFont; // 简单默认值 - 等于默认值时不序列化 [DefaultValue(typeof(Color), Yellow)] public Color HighlightColor { get; set; } Color.Yellow; // 隐藏 - 永远不序列化 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public Liststring RuntimeData { get; set; } // 条件序列化 public Font? CustomFont { get _customFont ?? Font; set { /* setter 逻辑 */ } } private bool ShouldSerializeCustomFont() _customFont is not null _customFont.Size ! 9.0f; private void ResetCustomFont() _customFont null; }重要对Component/Control派生类型的每个属性恰好使用上述三种方案之一。11. WinForms 设计原则11.1 核心规则缩放与 DPI使用充足的 margin/padding优先 TableLayoutPanelTLP/ FlowLayoutPanelFLP避免控件绝对定位TLP 单元格尺寸策略优先级行AutoSize Percent Absolute列AutoSize Percent Absolute新建 Form/UserControlAutoScaleMode与缩放假定 96 DPI/100%既有 Form保持AutoScaleMode原样不动但坐标相关属性要考虑缩放.NET 9 要感知 DarkMode用Application.IsDarkModeEnabled查询当前 DarkMode 状态注意DarkMode 下只有SystemColors的值会自动切换为互补色板因此 owner-draw 控件、自定义内容绘制、DataGridView 的主题/配色需要用绝对颜色值做定制。11.2 布局策略分而治之用多个或嵌套的 TLP 表达逻辑分区不要把一切塞进一个巨型网格主窗体使用 SplitContainer 或外层TLP用 % 或 AutoSize 行/列划分大区块每个 UI 区块拥有自己的嵌套 TLP或在复杂场景下用 UserControl 处理该区域细节。保持简单单个 TLP 最多 2–4 列用嵌套 TLP 的 GroupBox 保证清晰的视觉分组RadioButton 簇规则放在 AutoGrow/AutoSize GroupBox 内的单列、AutoSize 单元格 TLP 中大内容区滚动使用启用AutoScroll的嵌套 Panel 控件。TLP 单元格尺寸基本规则列标题列用 AutoSize配合Anchor Left | Right内容列用 Percent按合理推理分配百分比Anchor Top | Bottom | Left | Right单元格永远不要 Dock一律用 Anchor避免 Absolute 列尺寸模式除非是不可避免的定宽内容图标、按钮行单行特征的行典型输入字段、标题、复选框用 AutoSize多行 TextBox、渲染区域以及用于填充剩余空间的距离填充行例如底部 OK|Cancel 按钮行用 Percent行比列更应避免Absolute 尺寸模式Margin 很重要给控件设置Margin至少默认 3px注意Padding在 TLP 单元格中不起作用。11.3 常见布局模式单行 TextBox2 列 TLP——最常见录入模式Label 列AutoSize 宽度TextBox 列100% Percent 宽度LabelAnchor Left | Right与 TextBox 垂直居中TextBoxDock Fill设置Margin如四周 3px。多行 TextBox 或更大自定义内容 - 方案 A2 列 TLPLabel 与 TextBox 同行Anchor Top | LeftTextBoxDock Fill设置Margin行高AutoSize 或 Percent 决定单元格大小是单元格决定 TextBox 尺寸。多行 TextBox 或更大自定义内容 - 方案 B1 列 TLP分行放置Label 独占 TextBox 上方一行LabelDock Fill或Anchor LeftTextBox 在下一行Dock Fill设置MarginTextBox 所在行AutoSize 或 Percent。关键对多行 TextBox尺寸由 TLP 单元格定义而不是 TextBox 内容。11.4 容器尺寸关键——防止裁剪对 TLP 单元格内的 GroupBox/Panel必须设置AutoSize true且AutoSizeMode GrowOnly在单元格中Dock Fill父 TLP 对应行应为 AutoSizeGroupBox/Panel 内部内容使用嵌套 TLP 或 FlowLayoutPanel。为什么固定高度的容器即使父行是 AutoSize 也会裁剪内容——容器上报的是固定尺寸破坏了尺寸传递链。11.5 模态对话框按钮放置模式 A - 右下角按钮OK/Cancel 的标准做法按钮放入 FlowLayoutPanelFlowDirection RightToLeft按钮与内容之间保留一个百分比填充行FLP 放在主 TLP 的底部行按钮视觉顺序[OK]左[Cancel]右。模式 B - 右上角堆叠按钮向导/浏览器类按钮放入 FlowLayoutPanelFlowDirection TopDownFLP 放在主 TLP 的独立最右列该列AutoSizeFLPAnchor Top | Right顺序[OK] 在 [Cancel] 之上。适用场景模式 A 用于数据录入对话框、设置、确认框模式 B 用于多步向导、导航密集型对话框。11.6 复杂布局、模态对话框与其他控件复杂布局为逻辑区块创建专用 UserControl再嵌套到外层TLP 中并用DataContext传递数据Tab 页界面每个 TabPage 只用一个 UserControl可保持设计器代码可控。模态对话框规则方面规则对话框按钮顺序 → 主按钮OKAcceptButton、DialogResult OK次按钮CancelCancelButton、DialogResult Cancel关闭策略DialogResult隐式生效无需额外代码校验在Form 层执行而不是字段层绝不能用CancelEventArgs.Cancel true阻止焦点切换使用 Form 的DataContext属性.NET 8传递并取回模态数据对象。布局速查表窗体类型结构MainFormMenuStrip、可选 ToolStrip、内容区、StatusStrip简单录入窗体录入字段主要分布在左侧右侧仅一列按钮模态窗体设置有意义的MinimumSize选项卡仅用于职责明确的任务数量最小化、标签简短可访问性关键为可操作控件设置AccessibleName与AccessibleDescription用TabIndex维护逻辑制表顺序可访问性跟随控件添加顺序验证纯键盘导航、无歧义的助记符、读屏器兼容性。TreeView 与 ListView控件规则TreeView必须有可见的、默认展开的根节点ListView列数较少的小列表优先于 DataGridView内容设置在代码中生成不要写进设计器背后代码ListView 列填充后设为-1按最长内容缩放或-2按表头名缩放SplitContainer与 TreeView/ListView 搭配实现可调整面板DataGridView优先使用启用双缓冲的派生类DarkMode 下要配置颜色大数据分页/虚拟化VirtualMode True配合CellValueNeeded。资源与本地化UI 显示用的字符串字面量常量必须放入资源文件布局时要考虑本地化文本长度可能不同尽量不用图标库尝试用字体 Segoe UI Symbol 渲染图标确需图片时编写一个从该字体按指定尺寸渲染符号的辅助类。12. 关键提醒Critical Reminders文档末尾用一张 7 条清单收束全文对应原文第 618–628 行可作为代码生成后的自检表#规则1InitializeComponent代码是序列化格式——更像 XML而不是 C#2两种上下文、两套规则——设计器背后代码 vs 常规代码3生成代码前先校验窗体/控件名4严格遵守InitializeComponent编码风格规则5设计器文件绝不使用 NRT 注解6现代 C# 特性仅用于常规代码7数据绑定把 ViewModel 当作 DataSource记住Command与CommandParameter属性13. 实践建议如何在 awesome-copilot 中使用该 Agent结合仓库文档使用路径可归纳为三步安装按 docs/README.agents.md 指引在 VS Code / VS Code Insiders 中点击 WinForms Expert 的安装按钮或把 agents/WinFormsExpert.agent.md 直接下载到工作仓库例如.github/agents/或仓库约定的 agents 目录触发场景当任务涉及新建 WinForms 项目重构现有 Form/UserControl把 WinForms 项目改造为 MVVM修复设计器解析错误时让 Copilot 以 WinForms Expert 身份工作即可让生成代码自动遵循本文第 3–12 节的全部规则版本前提规范中各特性依赖运行时版本——DarkMode API 需 .NET 9MVVM 绑定/DataContext需 .NET 8异步 Form 方法与InvokeAsync新重载需 .NET 9而 Agent 本身建议项目整体基于 .NET 10 并假定 Windows 10.0.22000.0 及以上若目标环境低于这些版本应对应裁剪相关章节的适用范围。该 Agent 的规范完全以设计器兼容性为第一优先级组织内容它把 WinForms 最容易踩坑的两类问题——设计器序列化被现代 C# 语法破坏、以及布局/DPI/暗黑模式下控件行为不一致——各自落成可逐条执行的规则表和完整代码范例并辅以第 12 节的 7 条自检提醒适合作为团队在 AI 辅助生成 WinForms 代码时的统一验收基线。【免费下载链接】awesome-copilotCommunity-contributed instructions, agents, skills, and configurations to help you make the most of GitHub Copilot.项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-copilot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考