Skip to content

Fixes PrintPreviewControl displays a black preview page after assigning an empty PrintDocument - #14857

Open
ricardobossan wants to merge 2 commits into
dotnet:mainfrom
ricardobossan:Issue_14838_PrintPreviewControl_displays_a_black_preview
Open

Fixes PrintPreviewControl displays a black preview page after assigning an empty PrintDocument#14857
ricardobossan wants to merge 2 commits into
dotnet:mainfrom
ricardobossan:Issue_14838_PrintPreviewControl_displays_a_black_preview

Conversation

@ricardobossan

@ricardobossan ricardobossan commented Aug 6, 2026

Copy link
Copy Markdown
Member

Fixes #14838

Proposed changes

  • In PrintPreviewControl.DrawPages, the page-background fill now uses Color.White only when ForeColor was never explicitly set; an explicitly set ForeColor is still honored, as it has always been since the original .NET Framework port (uses the existing _isForeColorSet flag added by Fixes WinForms PrintPreviewControl ForeColor displays incorrectly only when set to White #14424).
  • Added unit tests covering both cases: default ForeColor renders white, explicit ForeColor renders that color.

Customer Impact

  • Fixes the solid-black preview page reported for a PrintDocument that produces no printable content, with ForeColor left at its default.
  • Apps that explicitly set ForeColor to customize the page background keep working exactly as before; no behavior change for them.

Regression?

Risk

Screenshots

Before

before_fix

After

after_fix

Test methodology

  • Unit tests

Test environment(s)

  • 11.0.100-preview.6.26359.118
Microsoft Reviewers: Open in CodeFlow

…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
@ricardobossan ricardobossan self-assigned this Aug 6, 2026
@ricardobossan
ricardobossan requested a review from a team as a code owner August 6, 2026 01:14
@ricardobossan ricardobossan added the waiting-review This item is waiting on review by one or more members of team label Aug 6, 2026
SimonZhao888
SimonZhao888 previously approved these changes Aug 6, 2026
@SimonZhao888

Copy link
Copy Markdown
Member

Looks good to me!

Comment thread src/System.Windows.Forms/System/Windows/Forms/Printing/PrintPreviewControl.cs Outdated
@dotnet-policy-service dotnet-policy-service Bot added the waiting-author-feedback The team requires more information from the author label Aug 6, 2026
@dotnet-policy-service dotnet-policy-service Bot removed the waiting-author-feedback The team requires more information from the author label Aug 7, 2026
@ricardobossan
ricardobossan requested a review from LeafShi1 August 7, 2026 01:30
// 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())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_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.

Image

@LeafShi1

LeafShi1 commented Aug 7, 2026

Copy link
Copy Markdown
Member

We have made several rounds of changes regarding the color issue with PrintPreviewControl. However, I feel that if we continue to use ForeColor to control both the message and the PrintDocument within the PrintPreviewControl, it will be difficult to achieve a satisfactory result for both elements.

I have two ideas:

  1. Revisit the original issue ([Accessibility] The text "Document does not contain any pages" in printPreviewControl has low color contrast #12365). Instead of changing the message color, we could change the PrintPreviewControl background color to a darker gray. I’ve noticed that the contrast is insufficient not only between the message and the control's background but also between the control's background and the form itself. I discussed this with Olina, and we consider it a valid issue. I’m wondering if using a darker gray for the PrintPreviewControl background might solve both problems simultaneously—though I acknowledge this would be a breaking change.

    image
  2. If we set aside the contrast issue between the PrintPreviewControl background and the form, could we add a separate property for PrintDocument—such as PageBackColor—to control the document's background color, while using the PrintPreviewControl's ForeColor solely to control the message color? This might be a more suitable approach.

What are your thoughts on this? @ricardobossan @KlausLoeffelmann

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-review This item is waiting on review by one or more members of team

Projects

None yet

3 participants