本文へ移動
cccskills
無料GitHub で公開

winforms-expert

Create, modify, debug, or review Windows Forms applications only when the request contains a concrete Windows Forms marker. USE FOR: WinForms, Windows Forms, System.Windows.Forms, WinForms Form or UserControl designer files (*.Designer.cs or *.Designer.vb), Visual Studio WinForms Designer, TableLayoutPanel, BindingSource, DataGridView, Control.InvokeAsync, component-tray ownership, or custom control serialization. DO NOT USE FOR: WPF or WPF XAML, including Window.InputBindings, KeyBinding, commands, or DataContext; .NET MAUI; Avalonia; or any request where none of the listed Windows Forms markers is present.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md22.6 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

WinForms Expert

Purpose

Implement WinForms changes that compile, behave correctly at runtime, and remain editable in the Visual Studio Designer. Treat InitializeComponent and *.Designer.* as a serialization format, not ordinary application code; keep behavior in the main partial class and verify designer usability whenever the environment permits.

Execution Contract

Before editing, list the workspace root and locate any task-specific validator, test script, or documented verification command. Read its scenario selector and required arguments before choosing an implementation. After editing:

  1. Run that narrow validator first and fix every failure it attributes to the change.
  2. Run the focused project build after the validator passes.
  3. If the build or any later edit changes source, rerun the narrow validator.
  4. Report those commands separately from runtime UI and Designer round-trip checks.

A successful build never substitutes for an available layout, binding, serialization, or designer-safety validator. Do not finish after merely reading a validator or after a build succeeds.

Use the repository's actual command and arguments; the sequence should look like:

pwsh -NoProfile -File <task-validator.ps1> <scenario-arguments>
dotnet build <project> --nologo

Boundaries

Use this skill for:

  • Creating or changing a WinForms project, Form, UserControl, or custom control.
  • Editing designer-generated layout, event wiring, resources, or component fields.
  • Diagnosing a Form Designer load, serialization, scaling, binding, or toolbox problem.
  • Implementing WinForms-specific async, MVVM, accessibility, DPI, or dark-mode behavior.

Do not use it to:

  • Convert the application to another UI framework unless the user explicitly requests migration.
  • Rewrite working generated code for style alone.
  • Change the target framework, language version, SDK, package strategy, startup model, DPI mode, or application-wide theme unless required by the request.
  • Claim that the Visual Studio Designer works when it was not actually opened and exercised.

Inputs

InputRequiredHow to obtain it
Requested UI behavior or defectYesUse the user's request and reproduce the symptom when possible.
Project language and target frameworkYesInspect the project file; do not assume modern .NET or C#.
Existing Form/UserControl partial filesYesFind the main file, designer file, and matching .resx.
Repository conventionsYesInspect nearby WinForms types, build scripts, analyzers, and package management.
Designer availabilityNoDetermine whether a compatible Visual Studio WinForms Designer can be opened.

Non-Negotiable Designer Contract

There are two code contexts:

ContextFilesRule
Designer serialization*.Designer.cs, *.Designer.vb, InitializeComponentUse simple, deterministic statements the designer can parse and regenerate.
Application behaviorMain partial class, services, view modelsUse language features supported by the project's TFM and language version.

In InitializeComponent and designer files:

  • Keep control/component construction, property assignments, collection additions, layout suspension/resumption, resource application, and named event-handler wiring.
  • Use class-level control/component fields. Do not add a control to Controls, Items, Columns, or another serialized collection through a local variable.
  • Use named event handlers defined in the main partial file. Never use lambdas or anonymous delegates in generated event wiring.
  • Do not add control flow (if, loops, switch, try/catch, lock, await, goto), local functions, expression-bodied logic, collection expressions, null-conditional or null-coalescing expressions, or other runtime decision logic.
  • Do not add business logic, data loading, validation, service calls, or methods other than the established generated members such as InitializeComponent and Dispose.
  • Preserve the generator's existing namespace style, qualification style, ordering, resources, and nullable treatment. Do not modernize generated syntax.
  • Preserve existing constructors that the designer relies on. A designer-instantiated Form/UserControl must have a usable parameterless construction path unless the project uses an established custom designer pattern.
  • Keep BeginInit/EndInit, SuspendLayout/ResumeLayout, and container ownership balanced.
  • For C#, keep generated fields at class scope in the designer partial. For VB, preserve Friend WithEvents fields and prefer Handles clauses in the main file.

A safe InitializeComponent sequence is:

  1. Instantiate controls and components.
  2. Instantiate the IContainer when owned components require it.
  3. Call required BeginInit and SuspendLayout methods.
  4. Assign child control/component properties.
  5. Add children to serialized collections and wire named handlers.
  6. Configure the containing Form/UserControl after its children.
  7. Call matching EndInit, ResumeLayout, and PerformLayout where appropriate.
  8. Declare serialized backing fields in the generator's established location.

Move anything more complex to the main partial class, usually after InitializeComponent has run.

Rules That Change the Answer

Use the symptom to choose one WinForms-specific repair. Do not list several plausible patterns when the existing project and failure identify one.

Symptom or requestDoNeverVerify
A Form/UserControl builds but the Designer cannot instantiate itPreserve the runtime constructor, add a designer-usable parameterless path, and defer dependency use until runtime load with an explicit design/null guardConstruct production services, open files, or query data from the designer pathThe runtime composition root still supplies the real dependency; the design path reaches InitializeComponent without invoking it
Controls/components disappear, duplicate, or fail after Designer save/reopenRestore the generated field/collection shape and balance every BeginInit/EndInit and SuspendLayout/ResumeLayout pairPatch the symptom in OnLoad or move serialized controls into local variablesSave, close, reopen, and inspect the regenerated diff
A designer-created Timer, BindingSource, image list, or similar component outlives the FormCreate the components container and pass it to the component constructorAdd ad hoc disposal while leaving designer ownership inconsistentClosing the Form disposes the container-owned component and the component remains designer-managed
Adding/removing list items does not refresh a bound WinForms list controlUse BindingList<T> or the repository's adapter that raises WinForms list-change notificationsTreat ObservableCollection<T> as a drop-in WinForms DataSourceMutate the list after binding and observe the control update
Nested content clips at DPI, font, or localization changesInspect AutoSize, AutoSizeMode, Dock, MinimumSize, MaximumSize, and row/column styles from the leaf through every parent; remove the actual growth cap while preserving intentional minimums; also inspect sibling controls positioned against the growing chain and keep them in responsive layoutAssume AutoSize = true is sufficient, increase one fixed Size, bypass a parent container, or leave a sibling where expanded content can overlap itExercise resize plus the relevant DPI/font/text expansion
UI work is posted but completion/errors are lostPut the operation in a Task-returning method that callers/tests can await; let the required async void event handler do only await RefreshAsync(); update controls on the captured WinForms context or await InvokeAsync when execution can be off-context; restore control state in finallyKeep the whole operation inside async void, use _ =, BeginInvoke, a dead cancellation catch, or an application-wide exception hook as the normal pathAwait the task-returning method through success and failure; verify the UI entry point delegates to it
Text must be localizableUse the existing .resx and ComponentResourceManager.ApplyResources serialization patternLeave fallback UI text hard-coded in InitializeComponentBuild, switch culture when possible, and perform a Designer save/reopen
A VB app needs startup, single-instance, or unhandled-UI hooksExtend ApplicationEvents.vb; qualify Microsoft.VisualBasic.ApplicationServices event-argument types when ambiguous; restore, activate, and bring the existing MainForm forward; log e.Exception; set e.ExitApplication = True explicitlyInvent Program.vb, add Sub Main, replace generated startup, or leave post-error continuation implicitThe configured StartupObject and generated application file remain unchanged, no new entry point exists, and the final report states the exit choice
Review finds no actual designer defectLeave tracked project/source files byte-for-byte unchanged and report why the suspicious construct is harmlessClean up warnings, reformat generated code, or modernize unrelated syntaxRun the narrow available check and focused build; confirm the source diff is empty
The workspace contains a task-specific validator or test scriptRun the narrow repository-provided check after editing and before the generic build; treat its failure as evidence that the change is incompleteSkip the specialized check because the project compiles, or claim a Designer round trip from static validationReport the exact validator and build commands separately, then state whether runtime UI and Designer round-trip checks were actually available

Workflow

1. Establish the project constraints

  1. Inspect the solution/project, target framework, language, nullable setting, package management, application startup, and existing build commands.
  2. Identify whether the app targets modern .NET or .NET Framework. Preserve its current family unless migration is requested.
  3. Read the complete partial-file set and .resx for every affected Form/UserControl before editing. Check base classes and nearby controls for repository conventions.
  4. If the defect is designer-specific, record the exact load/serialization error and determine whether the problem occurs before making broad changes.

2. Plan the serialization boundary

  1. Classify each change as serialized UI state or runtime behavior.
  2. Put only designer-representable state in InitializeComponent.
  3. Put conditional setup, dynamic content, data loading, conversions, validation, and service interaction in the main partial class or another runtime type.
  4. Prefer the smallest designer diff. Do not reorder or reformat the whole generated file.
  5. If editing generated code is avoidable, use the Designer or a runtime initialization method instead. If direct editing is necessary, follow the existing generated shape exactly.

3. Implement the UI structure

For new or substantially revised layouts:

  • Prefer TableLayoutPanel, FlowLayoutPanel, SplitContainer, and nested UserControls over brittle absolute positioning.
  • Divide complex screens into small layout regions. Avoid a single oversized grid.
  • Prefer AutoSize for caption/single-line rows and columns, Percent for expandable content, and Absolute only for genuinely fixed-size content.
  • Preserve the existing form's AutoScaleMode. For new forms, choose scaling deliberately based on the project conventions rather than copying coordinates from another DPI.
  • Ensure an autosized child container participates in the full sizing chain; a fixed-height Panel or GroupBox inside an autosized row can still clip its contents.
  • Set meaningful minimum sizes where a resizable or localized dialog could otherwise become unusable.
  • Keep localized UI text in the project's resources and allow labels/buttons to grow.

For dialogs:

  • Set AcceptButton, CancelButton, and appropriate DialogResult values.
  • Validate the form as a whole when submitting. Do not trap users in a field by canceling every focus change.
  • Dispose modal forms according to the project's ownership pattern.

4. Add behavior outside generated code

  • Follow the project's language and style conventions; modern syntax belongs only in regular code.
  • Keep UI-thread affinity explicit. Marshal control access from background work.
  • A normal WinForms async void event handler resumes on its captured UI synchronization context after await unless that context was deliberately bypassed. Direct control access there is valid. Use and await InvokeAsync when code can continue off-context, or when the task/repository contract explicitly requires a marshaled operation; do not rely on an unawaited post.
  • For modern .NET versions that support it, select the Control.InvokeAsync overload matching whether the delegate is synchronous/asynchronous and whether it returns a value. Await the returned operation; do not create fire-and-forget UI work.
  • async void is acceptable for WinForms event handlers and overrides that must return void, but catch exceptions around awaited work, handle cancellation intentionally, and surface unexpected failures through the application's established error path.
  • Do not use application-level exception hooks as a substitute for handling expected failures. Application.ThreadException covers UI-thread exceptions; AppDomain.UnhandledException is primarily a last-chance logging path and does not make continued execution safe.
  • Preserve property allocation semantics. Do not change a cached property into => new ... or vice versa without confirming lifetime and disposal behavior.

For application-wide startup:

  • Preserve the current startup model. C# projects may configure application defaults in Program.cs; VB projects normally use the VB Application Framework and ApplicationEvents.vb, not a newly invented Program.vb.
  • Use the APIs available to the actual TFM. Apply color mode or DPI defaults only when requested or consistent with the app's existing policy.
  • Prefer SystemAware when maintaining the normal .NET WinForms DPI behavior. Use PerMonitorV2 only when the application is designed and tested for per-monitor scaling.

5. Implement binding and serialization deliberately

For classic binding:

  • Use INotifyPropertyChanged for mutable bound objects and BindingList<T> or an established adapter for list change notifications.
  • Use BindingSource as the designer/runtime mediator when that matches the existing design.
  • Put conversion logic in Binding.Format and Binding.Parse handlers rather than embedding executable logic in designer code.
  • Treat one-way-to-source requests carefully: classic WinForms Binding does not provide a direct WPF-style mode. Document and test any workaround instead of implying native support.

For modern WinForms MVVM APIs, first confirm the TFM contains the requested API:

  • Use Control.DataContext for ambient view-model context when available.
  • Use ButtonBase.Command, ToolStripItem.Command, and CommandParameter when available.
  • Keep view models in a UI-independent project when the solution already uses that separation or the requested change benefits from it; do not add a new architecture for a small fix.
  • If design-time object data sources are required, preserve or add the project's established .datasource and BindingSource pattern and verify it in the Designer.

For custom Component/Control properties, choose one intentional CodeDOM serialization policy:

PolicyMechanismUse
Serialize only when non-default[DefaultValue(...)] or matching ShouldSerializeX/ResetXStable values with a meaningful default
Never serialize[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]Runtime-only, calculated, or unsupported state
Serialize contentDesignerSerializationVisibility.Content plus designer-compatible mutable contentOwned nested objects/collections intentionally edited in the property grid

Import System.ComponentModel (or fully qualify its attributes). Keep default metadata and runtime initialization directly aligned: for [DefaultValue(typeof(Color), "Yellow")], initialize the property or its backing field directly with Color.Yellow; do not hide the actual default behind a second constant or factory. Do not combine contradictory policies. Test property-grid editing and save/reload behavior for custom serialization changes.

6. Check usability and accessibility

  • Set logical TabIndex order and verify keyboard-only traversal.
  • Add unambiguous mnemonics where the product uses them.
  • Set meaningful accessible names/descriptions for actionable controls when labels or context do not already provide them.
  • Verify default focus, accept/cancel behavior, resizing, clipping, and localized text growth.
  • Check at the DPI/theme combinations relevant to the change. System colors adapt to theme; hard-coded colors and owner-drawn controls do not.
  • For owner drawing, DataGridView, icons, and custom painting, verify contrast in every supported theme rather than assuming dark-mode adaptation.

7. Validate in increasing-cost order

  1. Re-read the designer diff and confirm every statement is serialization-safe and every referenced field/handler exists in the correct partial class.
  2. Discover and run the repository's narrowest task-specific validation script or test when one is present. A generic build does not replace a designer/layout/binding validator.
  3. Run the repository's smallest applicable restore/build/analyzer command. Use Visual Studio MSBuild when the project type or .NET Framework dependencies require it.
  4. Run any remaining relevant automated tests.
  5. Launch the affected UI when possible and exercise creation, load, resize, keyboard navigation, binding, async/error paths, and close/disposal behavior.
  6. When Visual Studio with a compatible WinForms Designer is available:
    1. Open every changed Form/UserControl in the Designer.
    2. Confirm the design surface, toolbox integration, property grid, component tray, and inherited controls load without errors.
    3. Make a harmless reversible property change, save, close, reopen, and confirm the designer can serialize and reload the component.
    4. Revert only the harmless validation change, not the requested implementation.
    5. Build again after the serialization round trip.

Observable Completion Criteria

A change is complete only when the checks applicable to the environment are observable:

  • The project builds with no new compiler or analyzer errors.
  • Relevant tests pass.
  • The affected UI runs and the requested behavior is exercised, when launching is possible.
  • No affected InitializeComponent contains unsupported runtime logic or unresolved fields, handlers, resources, or unbalanced layout/initialization calls.
  • Changed custom properties survive a property-grid save/reopen round trip when applicable.
  • Every changed Form/UserControl opens and reloads in the compatible Visual Studio Designer when designer access is available.

If Visual Studio, the Designer, Windows desktop access, a required workload, or a target runtime is unavailable, report that validation as not run, state why, and list the exact checks that did run. A successful build is not evidence that the Designer opens. Do not report the work as fully designer-verified unless the design surface and serialization round trip were actually tested.

If a command fails:

  1. Report the command and the first actionable error.
  2. Distinguish a failure caused by the change from a missing tool/workload, incompatible platform, locked file, restore/network failure, or pre-existing repository failure.
  3. Fix failures caused by the change and rerun the check.
  4. Never replace a failed check with a success-shaped fallback or claim completion based only on source inspection.

Finish with a concise validation record:

  • Build: exact command and result.
  • Runtime UI: exercised behavior, or not run with the blocking reason.
  • Designer round trip: Form/UserControl opened, edited, saved, closed, and reopened; or not run with the blocking reason.
  • Preserved: project policy and generated/startup files intentionally left unchanged.

Common Pitfalls

PitfallCorrective rule
Treating InitializeComponent as normal modern C#Keep it as simple designer serialization; move decisions and behavior to the main partial class.
Putting lambdas or local control variables in generated codeUse class-level fields and named handlers.
Editing only one partial fileRead and keep the main file, designer file, .resx, base type, and project metadata consistent.
Reformatting the entire designer fileMake a surgical diff that follows generated ordering and style.
Assuming a build proves designer healthOpen, edit, save, close, and reopen the design surface.
Adding constructor dependencies to a designable typePreserve a designer-usable parameterless path or an established custom designer solution.
Fixed-size nested containers clipping controlsPreserve an autosizing chain and test resize plus DPI scaling.
Using absolute colors for dark mode without testingPrefer system colors or explicitly theme and contrast-test custom drawing.
Treating ObservableCollection<T> as a drop-in WinForms list sourceUse BindingList<T> or an adapter that bridges collection and property notifications.
Assuming WPF binding or converter features existUse WinForms Binding, BindingSource, Format, and Parse; verify TFM-specific APIs.
Fire-and-forget UI marshaling or uncaught async event errorsAwait InvokeAsync; catch and surface failures in async void UI entry points.
Inventing Program.vb for a VB applicationUse the VB Application Framework and ApplicationEvents.vb conventions.
Changing DPI/theme/TFM/package policy during a UI fixPreserve project policy unless the requested behavior requires and validates the change.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Route gh-aw workflow design/create/debug/upgrade requests to the right prompts.

日本語の概要は準備中です。原文の説明を表示しています。

dotnet/skills5,5992026年10月11日 更新

Scans .NET code for ~50 performance anti-patterns across async, memory, strings, collections, LINQ, regex, serialization, and I/O with tiered severity classification. Use when analyzing .NET code for optimization opportunities, reviewing hot paths, or auditing allocation-heavy patterns.

日本語の概要は準備中です。原文の説明を表示しています。

dotnet/skills5,5992026年10月11日 更新

Symbolicate the .NET runtime frames in an Android tombstone file. Extracts BuildIds and PC offsets from the native backtrace, downloads debug symbols from the Microsoft symbol server, and runs llvm-symbolizer to produce function names with source file and line numbers. USE FOR triaging a .NET MAUI or Mono Android app crash from a tombstone, resolving native backtrace frames in libmonosgen-2.0.so or libcoreclr.so to .NET runtime source code, or investigating SIGABRT, SIGSEGV, or other native signals originating from the .NET runtime on Android. DO NOT USE FOR pure Java/Kotlin crashes, managed .NET exceptions that are already captured in logcat, or iOS crash logs. INVOKES Symbolicate-Tombstone.ps1 script, llvm-symbolizer, Microsoft symbol server.

日本語の概要は準備中です。原文の説明を表示しています。

dotnet/skills5,5992026年10月11日 更新

Symbolicate .NET runtime frames in Apple platform .ips crash logs (iOS, tvOS, Mac Catalyst, macOS). Extracts UUIDs and addresses from the native backtrace, locates dSYM debug symbols, and runs atos to produce function names with source file and line numbers. Automatically downloads .dwarf symbols from the Microsoft symbol server using Mach-O UUIDs. USE FOR triaging a .NET MAUI or Mono app crash from an .ips file on any Apple platform, resolving native backtrace frames in libcoreclr or libmonosgen-2.0 to .NET runtime source code, retrieving .ips crash logs from a connected iOS device or iPhone, or investigating EXC_CRASH, EXC_BAD_ACCESS, SIGABRT, or SIGSEGV originating from the .NET runtime. DO NOT USE FOR pure Swift/Objective-C crashes with no .NET components, or Android tombstone files. INVOKES Symbolicate-Crash.ps1 script, atos, dwarfdump, idevicecrashreport.

日本語の概要は準備中です。原文の説明を表示しています。

dotnet/skills5,5992026年10月11日 更新

Analyze assertion quality, depth, variety, and false confidence in existing tests. ALWAYS USE when asked about weak, shallow, trivial, always-true, self-referential, assertion-free, presence/truthiness-only, or insufficiently diverse assertions, including MSTest, Jest, pytest, and Go. DO NOT USE for direct fixes: writing-mstest-tests owns supplied MSTest assertions; code-testing owns new cases. Use test-gap-analysis when asked whether tests would catch a production change, and test-anti-patterns for general severity-ranked audits.

日本語の概要は準備中です。原文の説明を表示しています。

dotnet/skills5,5992026年10月11日 更新

Create or review Blazor components (.razor files) with correct architecture. USE FOR: writing new Blazor components that do NOT involve JavaScript interop, implementing parameters and EventCallback, RenderFragment slots, component lifecycle (OnInitializedAsync, OnParametersSet), async patterns, IAsyncDisposable, CancellationToken, CSS isolation, code-behind. DO NOT USE FOR: creating new projects (use create-blazor-project), JavaScript interop or calling browser APIs from Blazor (use use-js-interop), forms and validation (use collect-user-input), prerendering issues (use support-prerendering), HTTP data fetching patterns (use fetch-and-send-data), coordinating state between unrelated components (use coordinate-components).

日本語の概要は準備中です。原文の説明を表示しています。

dotnet/skills5,5992026年10月11日 更新

dotnet のスキルをすべて見る

このスキルの問題を報告する