-
Notifications
You must be signed in to change notification settings - Fork 1k
Update the OwnerDraw flag when BackgroundImage changes #13824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Update the OwnerDraw flag when BackgroundImage changes #13824
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes an issue where Button controls with BackgroundImage fail to render properly in dark mode when using FlatStyle.Standard. The problem occurs due to premature evaluation of the BackgroundImage property during early initialization before the control's handle is created.
- Adds an
IsHandleCreated
check to theOwnerDraw
property logic - Delays the BackgroundImage null check until after handle creation
- Ensures buttons with BackgroundImage properly use custom dark mode rendering
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/Button.cs
Outdated
Show resolved
Hide resolved
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/Button.cs
Outdated
Show resolved
Hide resolved
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #13824 +/- ##
===================================================
+ Coverage 77.10424% 77.13077% +0.02652%
===================================================
Files 3273 3273
Lines 644936 644932 -4
Branches 47692 47693 +1
===================================================
+ Hits 497273 497441 +168
+ Misses 143982 143820 -162
+ Partials 3681 3671 -10
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
@Epica3055, how is tbis related to the changes for RC2? |
…nerDraw flag to ensure correct visual behavior
This fix is unrelated to RC2.
|
Makes sense. @LeafShi1, @Epica3055: If we would get green light for RC2, this would need to be back ported. Thanks! |
src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/Button.cs
Show resolved
Hide resolved
@KlausLoeffelmann @merriemcgaw Based on the test results of this PR, I need to confirm should If
If we decide to enable winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/RadioButton.cs Lines 174 to 185 in 9634900
|
e17e417
to
6da3eca
Compare
6da3eca
to
9e82a5f
Compare
@@ -549,15 +549,13 @@ internal void PaintImage(PaintEventArgs e, LayoutData layout) | |||
{ | |||
if (Application.IsDarkModeEnabled && Control.DarkModeRequestState is true && Control.BackgroundImage is not null) | |||
{ | |||
Rectangle bounds = Control.ClientRectangle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I do not understand is:
When the Button has a border, why would the background "shine through"?
We paint:
- Background
- BackgroundImage
- Border
If we are not deflating the Bounds, aren't we then painting over the Image? What if the Image got important markers in its outer border?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the previous logic, our drawing order was incorrect.
- Background color
- Border
- Background image
This has now been corrected.
Under the original logic
- The background color was drawn according to the ClientRectangle (the background color and background image in Classic are drawn using rect.Inflate(-Control.FlatAppearance.BorderSize, -Control.FlatAppearance.BorderSize);).
- The border was drawn after indenting the ClientRectangle by one pixel (the border in Classic is drawn using r.Inflate(1, 1);).
- The background image was drawn after subtracting the ClientRectangle from Control.borderSize (the background image in Classic is drawn using rect.Inflate(-Control.FlatAppearance.BorderSize, -Control.FlatAppearance.BorderSize);)).
So, under dark mode, the background color size > the border size > the background image size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not holding this off, since it is too niche.
Let's take this as it is, so we can go forward.
@merriemcgaw FYI.
Fixes #13823
Root Cause
The
OwnerDraw
property of the Button control incorrectly returnsfalse
whenBackgroundImage
is set during early initialization. This is due to theOwnerDraw
logic checkingBackgroundImage == null
before the control's handle is created, which causes a premature fallback to the system renderer. As a result, even thoughBackgroundImage
is later assigned, it is ignored during rendering inFlatStyle.Standard
mode.Proposed changes
UpdateOwnerDraw
inBackgroundImage
property of Button.cs to update theOwnerDraw
flag to ensure correct visual behaviorCustomer Impact
Regression?
Risk
Screenshots
Before
The BackgroundImage of Button is not displayed when the FlatStyle is Standard in DrakMode

After
The BackgroundImage of Button displayed when the FlatStyle is Standard in DrakMode

Test methodology
Test environment(s)
Microsoft Reviewers: Open in CodeFlow