Fixes PrintPreviewControl displays a black preview page after assigning an empty PrintDocument - #14857
Conversation
…ng an empty PrintDocument Fixes dotnet#14838 ## Proposed changes - In `PrintPreviewControl.DrawPages`, fill each page rectangle with a fixed `Color.White` "paper" background instead of the control's `ForeColor`. - Added a regression unit test asserting a page with no drawable content renders white, not `ForeColor`. ## Customer Impact - Print preview pages render as white paper again, regardless of the control's `ForeColor`. - Fixes the solid-black preview page reported for a `PrintDocument` that produces no printable content, and removes the general risk of the page background matching a dark `ForeColor`. ## Regression? - Yes. Regression from dotnet#14424 (merged 2026-07-02), which correctly changed `ResetForeColor()`'s default from `Color.White` to `SystemColors.ControlText` to fix dotnet#14420. `DrawPages()` separately reused `ForeColor` to fill each page's background (present since the original .NET Framework port) and only rendered white by coincidence, because the old default happened to match. This PR doesn't touch dotnet#14424's changes (`ForeColor`, `ResetForeColor`, `ShouldSerializeForeColor`, `DrawMessage`), so dotnet#14420 stays fixed; it only changes the unrelated page-background fill in `DrawPages`. ## Risk - Low. Single fill-color change, scoped to the page-background rectangle in `DrawPages`. Verified it doesn't touch `ForeColor`, `ResetForeColor`, `ShouldSerializeForeColor`, `_isForeColorSet`, or `DrawMessage` (the members dotnet#14424 added/changed for dotnet#14420). - The white fill isn't theme-aware, matching how this code behaved from the original .NET Framework port through dotnet#14424 (`Color.White`). No issue, test, or doc comment in this control's history ties `ForeColor` to page-background color (dotnet#13861/dotnet#13863/dotnet#14420/dotnet#14424 are all specifically about the "no printable content" message text), so this restores the long-standing default rather than removing a documented capability. If someone was relying on `ForeColor` to tint the blank-page fill as a side effect, that (undocumented) behavior is gone; open to making it configurable separately if that's a real use case. ## Screenshots ### Before ### After ## Test methodology - Added `PrintPreviewControl_PageWithNoImage_RendersWhiteNotForeColor`: builds a `PrintPreviewControl` with `ForeColor = Color.Black` and injects a synthetic page with no image (`new PreviewPageInfo(image: null, physicalSize: ...)`, standing in for an empty `PrintDocument`'s output), renders to a bitmap, and asserts the page interior is white rather than black. - Confirmed the new test fails against the pre-fix code (reproducing the reported black page) and passes after the fix, to make sure it actually exercises the regression. - Ran the full `PrintPreviewControlTests` class locally: 8/8 passing. - Manually reproduced the issue end-to-end in `ScratchProject`: reverted the fix, rebuilt, confirmed the solid black page shown above, then restored the fix, rebuilt, and confirmed the page renders white (screenshots above). ## Test environment(s) - 11.0.100-preview.6.26359.118
|
Looks good to me! |
| // Default page fill is white (paper); an explicitly set ForeColor is still honored, | ||
| // as it always has been. | ||
| Color pageColor = _isForeColorSet ? ForeColor : Color.White; | ||
| using (var brush = pageColor.GetCachedSolidBrushScope()) |
There was a problem hiding this comment.
_isForeColorSet changes only when ForeColorChanged fires, but Control.ForeColor raises that event only when the effective color changes. Therefore:
control.ForeColor = SystemColors.ControlText;
does not set the flag because construction already assigned that color. The PR then renders white instead of honoring the explicit foreground color, unlike previous behavior. This can affect existing designer-generated code from when white was the default.
|
We have made several rounds of changes regarding the color issue with I have two ideas:
What are your thoughts on this? @ricardobossan @KlausLoeffelmann |

Fixes #14838
Proposed changes
PrintPreviewControl.DrawPages, the page-background fill now usesColor.Whiteonly whenForeColorwas never explicitly set; an explicitly setForeColoris still honored, as it has always been since the original .NET Framework port (uses the existing_isForeColorSetflag added by Fixes WinForms PrintPreviewControl ForeColor displays incorrectly only when set to White #14424).ForeColorrenders white, explicitForeColorrenders that color.Customer Impact
PrintDocumentthat produces no printable content, withForeColorleft at its default.ForeColorto customize the page background keep working exactly as before; no behavior change for them.Regression?
ResetForeColor()'s default fromColor.WhitetoSystemColors.ControlTextto fix WinForms PrintPreviewControl ForeColor displays incorrectly only when set to White #14420.DrawPages()separately reusedForeColorto fill each page's background (present since the original .NET Framework port) and only rendered white by coincidence, because the old default happened to match. This PR doesn't touch Fixes WinForms PrintPreviewControl ForeColor displays incorrectly only when set to White #14424's changes (ForeColor,ResetForeColor,ShouldSerializeForeColor,DrawMessage), so WinForms PrintPreviewControl ForeColor displays incorrectly only when set to White #14420 stays fixed; it only changes the unrelated page-background fill inDrawPages.Risk
Colorexpression inDrawPages, gated on the existing_isForeColorSetflag. Preserves the pre-Fixes WinForms PrintPreviewControl ForeColor displays incorrectly only when set to White #14424 behavior for explicitForeColor(per review feedback on this PR:ForeColorhas driven the page background since .NET Framework), and fixes the black-default regression for everyone else.Screenshots
Before
After
Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow