dotnet / dotnet/winforms

[API Proposal] Make ToolStrip.ImageScalingSize participate in AutoSize layout under VisualStylesMode.Net12

Open
#14,922 0 comments 0 reactions 0 assignees View on GitHub
api-suggestion area-Layout NewApi-Net12 untriaged
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
1d 13m
Merged PRs (30d)
85

Description

# Background and motivation

`ToolStrip.ImageScalingSize` influences image rendering today, but it does not participate in `AutoSize` layout in the intuitive way developers expect when no image-bearing item has yet been measured. This creates confusing runtime and Designer behavior: changing the property can fail to update ToolStrip bounds until image content participates in layout or the control is recreated.

The Designer hosts real WinForms controls, so this should be corrected in runtime layout rather than through Designer-only shadow state or recreation.

Companion Symbol API proposal: dotnet/winforms#14921.

# API Proposal

No new ToolStrip property is proposed. Under `VisualStylesMode.Net12`:

- when `AutoSize == true`, `ImageScalingSize` contributes to the ToolStrip cross-axis preferred-size calculation even when no current item contains an image;
- for horizontal ToolStrips, `ImageScalingSize.Height` contributes to minimum content height;
- for vertical ToolStrips, `ImageScalingSize.Width` contributes to minimum content width;
- changing `ImageScalingSize` invalidates preferred-size/layout state and immediately remeasures an AutoSize ToolStrip;
- existing visual-style modes retain current behavior.

The metric is an input, not the final control bounds. Normal layout still accounts for font/text, padding, margins, grip/chrome, renderer metrics, separators, arrows, and min/max size.

Current source evidence:

- The setter only performs layout work when items exist: [`ToolStrip.ImageScalingSize`](https://github.com/dotnet/winforms/blob/f724c2277a0695ca71d1816575636afc802d73b9/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs#L920-L935).
- Preferred image size is derived from actual image/image-list participation: [`ToolStripItem.PreferredImageSize`](https://github.com/dotnet/winforms/blob/f724c2277a0695ca71d1816575636afc802d73b9/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripItem.cs#L1552-L1575).
- Menu layout consumes `ImageScalingSize` inside the image path: [`ToolStripMenuItemInternalLayout`](https://github.com/dotnet/winforms/blob/f724c2277a0695ca71d1816575636afc802d73b9/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripMenuItem.ToolStripMenuItemInternalLayout.cs#L117-L127).
- Dropdowns already delegate internal image scaling metrics to their owner: [`ToolStripDropDown.ImageScalingSizeInternal`](https://github.com/dotnet/winforms/blob/f724c2277a0695ca71d1816575636afc802d73b9/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripDropDown.cs#L462-L467).

The default remains 16×16; this proposal changes measurement semantics only.

Open questions:

1. Should an empty AutoSize ToolStrip use `ImageScalingSize` as a cross-axis minimum?
2. Should `MenuStrip`, `StatusStrip`, `ContextMenuStrip`, and generated dropdowns inherit this uniformly?
3. How should `ImageScaling = None` interact with the strip-level layout hint?
4. Is a named `VisualStylesMode.Net12` member the right compatibility gate, or should the behavior follow `Latest` differently?

# API Usage

```CSharp
var toolStrip = new ToolStrip
{
AutoSize = true,
ImageScalingSize = new Size(24, 24),
};

// Under VisualStylesMode.Net12, this immediately remeasures the cross-axis
// even before an image-bearing item exists.
toolStrip.ImageScalingSize = new Size(32, 32);
```

# Alternative Designs

- Add a second layout-hint property. This duplicates intent and complicates the Designer/API model.
- Change behavior in all visual styles. This risks existing application layout without a compatibility gate.
- Implement a Designer-only shadow property or recreate ToolStrips. This splits runtime/design-time behavior and leaves the runtime bug intact.
- Document current behavior. This preserves an unintuitive propagation model and Designer roundtrips.

# Risks

- AutoSize bounds can change for applications opting into `VisualStylesMode.Net12`.
- Custom renderers and derived ToolStrips must continue to account for chrome and other content requirements.
- DPI rounding and min/max constraints must remain stable.
- MenuStrip, StatusStrip, and dropdown specializations may need targeted layout adjustments rather than a single base-class change.

# Will this feature affect UI controls?

Yes. The test matrix should include:

- horizontal and vertical orientation;
- empty, text-only, image-bearing, and mixed image/symbol strips;
- runtime changes before and after population;
- `ImageScaling` values `SizeToFit` and `None`;
- `AutoSize` true and false;
- `MinimumSize` / `MaximumSize`, padding, grip style, fonts, and custom renderers;
- ToolStrip, MenuStrip, StatusStrip, ContextMenuStrip, dropdowns, and custom derivatives;
- 100%, 150%, 200%, and per-monitor DPI changes;
- Designer property edits and serialization;
- legacy visual-style modes remaining unchanged.

Contributor guide

Open the contributing guide

Research direction

Read ToolStrip.ImageScalingSize in src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs, ToolStripItem.PreferredImageSize, ToolStripMenuItemInternalLayout, and ToolStripDropDown.ImageScalingSizeInternal. First trace preferred-size and layout invalidation for empty and image-bearing strips under VisualStylesMode.Net12. Done requires resolving the open questions and covering the listed orientations, strip types, scaling modes, DPI, constraints, renderers, and legacy visual-style behavior with tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
desktop
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.