[.NET 11 API Proposal] Visual Styles feature
api-suggestionarea-Theming
## Rationale
WinForms needs a versioned Visual Styles path that allows accessibility-driven rendering improvements to ship without breaking existing pixel-perfect applications. The feature should be opt-in, predictable, and specific to WinForms visual rendering rather than becoming a general theming system.
Classic `CheckBox` controls give users a very small practical landing area and use a design language that many customers no longer accept as modern. That matters for accessibility: small glyph-focused targets are harder for touch, pen, low-vision users, and users with motor impairments. Modern checkbox rendering should increase the practical hit target, make the state easier to recognize, and keep compatibility through explicit visual-style versioning.
`RadioButton` controls, also known as option buttons, have the same landing-area and visual-language problem. Since WinForms has already introduced new renderers for `Button`, extending the overhaul to the whole button family is a lower-risk and more coherent path than modernizing each control independently. The normal `Button` should also receive a .NET 11 visual style based on current Fluent Design styling, including rounded corners.
`TextBoxBase` is missing an effective `Padding` API. This is also an accessibility issue in dense forms. In particular, dark surfaces make the problem more visible: a white `TextBox` border on a dark background creates a much stronger contrast boundary than the complementary classic/light appearance. In forms with many `Label`/`TextBox` pairs, users can lose track of grouping and reading flow. Versioned Visual Styles give WinForms a compatibility-safe way to modernize `TextBox` rendering, expose padding, and improve spacing without forcing layout changes on existing applications.
### What this feature is and is not
* We have NO intention to introduce full-blown theming support in WinForms with this.
* We want to be very mindful with this topic, since there are a lot of theming standards already out there.
* The API is meant as an opt in: You can use it, but if you do not, nothing should break. Existing theming concepts should continue to work as they are.
## Versioning Visual Styles for current and future A11Y requirements
Visual Styles Mode versions how controls render in different .NET releases. This is essential for backward compatibility when accessibility requirements or platform design expectations require larger minimum sizes, different padding, different margins, updated hit testing, or updated border rendering.
In .NET 11, the first versioned Visual Styles target is `Net11`. Applications that do not opt in keep existing rendering. Applications that do opt in can use the .NET 11 rendering contract directly, use `Latest` to follow the latest stable Visual Styles contract, or use `LatestPreview` when they intentionally want preview/out-of-band Visual Styles behavior before it is promoted into a stable version.
The APIs are added to `Application` and `Control`, with `VisualStyles` in their names, so both new and existing applications can opt into enhanced rendering while maintaining compatibility with previous framework versions.
## API Proposal
```csharp
namespace System.Windows.Forms;
public enum VisualStylesMode : short
{
Classic = 0,
Disabled = 1,
Net11 = 2,
LatestPreview = short.MaxValue - 1,
Latest = short.MaxValue,
}
```
```csharp
namespace System.Windows.Forms;
public static partial class Application
{
public static VisualStylesMode DefaultVisualStylesMode { get; }
public static void SetDefaultVisualStylesMode(VisualStylesMode visualStylesMode);
}
```
```csharp
namespace System.Windows.Forms;
public partial class Control
{
public VisualStylesMode VisualStylesMode { get; set; }
public event EventHandler? VisualStylesModeChanged;
protected virtual void OnVisualStylesModeChanged(EventArgs e);
// Allows a derived control to set a particular Visual Styles mode for compatibility reasons.
protected virtual VisualStylesMode DefaultVisualStylesMode { get; }
}
```
```csharp
namespace System.Windows.Forms;
public abstract class TextBoxBase : Control
{
public new Padding Padding { get; set; }
}
```
```csharp
namespace System.Windows.Forms;
public enum Appearance
{
Normal = 0,
Button = 1,
ToggleSwitch = 2,
}
```
## API Usage
```csharp
Application.SetDefaultVisualStylesMode(VisualStylesMode.Net11);
Application.Run(new MainForm());
```
```csharp
Application.SetDefaultVisualStylesMode(VisualStylesMode.LatestPreview);
Application.Run(new VisualStylesPreviewForm());
```
```csharp
checkBox1.VisualStylesMode = VisualStylesMode.Net11;
checkBox1.Appearance = Appearance.ToggleSwitch;
textBox1.VisualStylesMode = VisualStylesMode.Net11;
textBox1.Padding = new Padding(8, 4, 8, 4);
```
## Alternative Designs
### Use only target-framework defaults
Visual Styles could be selected only by targeting a newer framework. That would make new applications simpler, but it would also make roll-forward and retargeting riskier for layout-sensitive WinForms applications. Explicit `VisualStylesMode` versioning keeps the compatibility decision under application control.
### Use a single `UseModernVisualStyles` switch
A boolean switch is not expressive enough once Visual Styles need to evolve across multiple framework releases. Versioned values allow .NET 11 behavior to remain stable while later releases add new versions.
### Add separate per-control feature flags
Separate flags for button rounding, checkbox rendering, textbox padding, and similar details would provide very granular control, but it would also make the feature harder to explain, test, and document. A single versioned mode keeps the opt-in surface coherent.
## Risks
- Updated control metrics can affect pixel-perfect layouts. The feature must remain opt-in and versioned.
- Rendering, hit testing, focus cues, UIA bounds, and keyboard behavior must stay aligned for the button family.
- `TextBoxBase.Padding` can change layout expectations for derived controls and must be constrained to Visual Styles modes where the new rendering contract applies.
- Owner-drawn controls, custom renderers, and inherited controls must have clear compatibility behavior.
- `LatestPreview` must be documented as intentionally unstable preview behavior and should not be serialized accidentally by tooling as a long-term stable target.
## Will this feature affect UI controls?
Yes. This feature intentionally affects rendering, spacing, and practical hit targets for selected controls when the application or control opts into a Visual Styles mode beyond classic behavior. The initial focus is the button family (`Button`, `CheckBox`, `RadioButton`) and `TextBoxBase`-derived controls.
Designer support is expected for localized property categories/descriptions and CodeDOM serialization-safe defaults. Existing applications that do not opt in should preserve their current rendering and layout behavior.
### Status Checklist
- [x] API proposal has `api-suggestion` label
- [x] Rationale, API Proposal, API Usage, and Risks sections are complete
- [ ] API shape has been discussed with the team
- [ ] Review the issue for compatibility with what the API review board expects
- [ ] Change label to `api-ready-for-review`
- [ ] If late in the release cycle, also add the `blocking` label to expedite the review appointment
- [ ] API review completed — label changed to `api-approved`
## Work tracker
- [x] Create Visual Styles only issue based on the original upstream dark-mode/Visual Styles issue: https://github.com/dotnet/winforms/issues/7641.
- [x] Explore `HighPrecisionTimer` option as an animation trigger based on process-limited [`timeBeginPeriod`](https://learn.microsoft.com/windows/win32/api/timeapi/nf-timeapi-timebeginperiod) behavior. Windows 10 version 2004 and later no longer apply a caller's requested timer resolution globally; earlier versions used a global timer-resolution setting.
- [ ] Explore option for non-client rendering in `Control` per se.
- [ ] Explore alpha transparency with GDI/GDI+ without replacement colors through Win32 layered windows. [`WS_EX_LAYERED`](https://learn.microsoft.com/windows/win32/winmsg/extended-window-styles) supports child windows on Windows 8 and later, and `UpdateLayeredWindow` can render 32-bpp ARGB per-pixel alpha without DirectX or DirectComposition.
- [ ] Extract useful, approved code from the .NET 9 PRs and port what still makes sense to .NET 11.
- [ ] Create exploratory test app to test new Visual Styles in combination with the new `KioskModeManager` APIs (#14586) and improved layout APIs (#14585).
0 条评论