diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxModernAdapter.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxModernAdapter.cs
index 6c506d87aaf..749eda02a6a 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxModernAdapter.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/CheckBoxModernAdapter.cs
@@ -124,10 +124,10 @@ private void PaintCore(PaintEventArgs e)
PaintImage(e, layout);
- Color preferredTextColor = Control.ShouldSerializeForeColor()
+ Color preferredTextColor = Control.ShouldSerializeForeColor() || Control.ForeColor != Forms.Control.DefaultForeColor
? Control.ForeColor
: Application.IsDarkModeEnabled
- ? Color.FromArgb(0xF0, 0xF0, 0xF0)
+ ? DarkModeButtonColors.DefaultColors.AcceptButtonTextColor // Use the default accept button text color in dark mode for checkboxes.
: SystemColors.WindowText;
Color disabledTextBackColor = Control.ShouldSerializeBackColor()
&& Control.BackColor.A == byte.MaxValue
diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeAdapter.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeAdapter.cs
index 3f9a112accf..c274360bf13 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeAdapter.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeAdapter.cs
@@ -55,7 +55,7 @@ private Color GetButtonTextColor(
}
bool useEffectiveForeColor = _modern
- ? Control.ShouldSerializeForeColor()
+ ? Control.ShouldSerializeForeColor() || Control.ForeColor != Forms.Control.DefaultForeColor
: Control.ForeColor != Forms.Control.DefaultForeColor;
if (useEffectiveForeColor)
@@ -95,11 +95,11 @@ private Color GetButtonBackColor(PushButtonState state)
}
else
{
- bool hasExplicitBackColor = Control.ShouldSerializeBackColor();
- bool hasUsableAmbientBackColor = !Control.BackColor.HasTransparency()
- && Control.BackColor != Forms.Control.DefaultBackColor;
+ bool hasCustomBackColor = _modern
+ ? Control.ShouldSerializeBackColor()
+ : Control.BackColor != Forms.Control.DefaultBackColor;
- if (hasExplicitBackColor || hasUsableAmbientBackColor)
+ if (hasCustomBackColor)
{
backColor = ButtonDarkModeRenderer.GetBackgroundColor(
state,
diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonModernAdapter.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonModernAdapter.cs
index 412d832507a..2d0aad26122 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonModernAdapter.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/RadioButtonModernAdapter.cs
@@ -124,10 +124,10 @@ private void PaintCore(PaintEventArgs e)
PaintImage(e, layout);
- Color preferredTextColor = Control.ShouldSerializeForeColor()
+ Color preferredTextColor = Control.ShouldSerializeForeColor() || Control.ForeColor != Forms.Control.DefaultForeColor
? Control.ForeColor
: Application.IsDarkModeEnabled
- ? Color.FromArgb(0xF0, 0xF0, 0xF0)
+ ? DarkModeButtonColors.DefaultColors.AcceptButtonTextColor // Use the default accept button text color in dark mode for radio buttons.
: SystemColors.WindowText;
Color disabledTextBackColor = Control.ShouldSerializeBackColor()
&& Control.BackColor.A == byte.MaxValue
diff --git a/src/System.Windows.Forms/System/Windows/Forms/Rendering/Button/AnimatedPopupButtonRenderer.cs b/src/System.Windows.Forms/System/Windows/Forms/Rendering/Button/AnimatedPopupButtonRenderer.cs
index 5a3967073c4..065c2bdb753 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Rendering/Button/AnimatedPopupButtonRenderer.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Rendering/Button/AnimatedPopupButtonRenderer.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Drawing;
@@ -9,7 +9,7 @@
namespace System.Windows.Forms.Rendering.Button;
///
-/// Drives and renders a whose is
+/// Drives and renders a whose is
/// when modern visual styles or dark mode are active, using the concave key-cap
/// look of .
///
@@ -119,6 +119,7 @@ public override void RenderControl(Graphics graphics)
Color faceColor;
Color foreColor;
Color borderColor;
+ bool useAutomaticForeColor = false;
if (highContrast)
{
@@ -138,9 +139,8 @@ public override void RenderControl(Graphics graphics)
faceColor = PopupButtonColorMath.Blend(baseColor, hoverColor, _hoverCurrent);
faceColor = PopupButtonColorMath.Blend(faceColor, pressedColor, _pressCurrent);
- bool useAutomaticForeColor = button.EffectiveVisualStylesModeInternal >= VisualStylesMode.Net11
- ? !button.ShouldSerializeForeColor()
- : button.ForeColor == Forms.Control.DefaultForeColor;
+ useAutomaticForeColor = button.ForeColor == Control.DefaultForeColor
+ && !button.ShouldSerializeForeColor();
foreColor = !useAutomaticForeColor
? button.ForeColor
: _baseColorRenderer.GetTextColor(state, button.IsDefault, faceColor);
@@ -157,9 +157,7 @@ public override void RenderControl(Graphics graphics)
BackColor = faceColor,
ForeColor = foreColor,
SurfaceColor = button.Parent?.BackColor ?? button.BackColor,
- UseAutomaticForeColor = button.EffectiveVisualStylesModeInternal >= VisualStylesMode.Net11
- ? !button.ShouldSerializeForeColor()
- : button.ForeColor == Forms.Control.DefaultForeColor,
+ UseAutomaticForeColor = useAutomaticForeColor,
BorderColor = borderColor,
BorderWidth = flatAppearance.BorderSize,
Enabled = button.Enabled,
@@ -233,12 +231,14 @@ public override void RenderControl(Graphics graphics)
internal (Color BaseColor, Color HoverColor, Color PressedColor) GetStateColors()
{
- Forms.ButtonBase button = Button;
+ ButtonBase button = Button;
FlatButtonAppearance flatAppearance = button.FlatAppearance;
_baseColorRenderer.DeviceDpi = button.DeviceDpi;
_baseColorRenderer.FlatAppearance = flatAppearance;
- bool hasCustomBackColor = button.BackColor != Forms.Control.DefaultBackColor;
+ bool hasCustomBackColor = button.EffectiveVisualStylesModeInternal >= VisualStylesMode.Net11
+ ? button.ShouldSerializeBackColor()
+ : button.BackColor != Control.DefaultBackColor;
Color baseColor = hasCustomBackColor
? button.BackColor
: _baseColorRenderer.GetBackgroundColor(PushButtonState.Normal, isDefault: false);
diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/ButtonVisualStylesTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/ButtonVisualStylesTests.cs
index cbb0ecb7d71..3854f09a295 100644
--- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/ButtonVisualStylesTests.cs
+++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/ButtonVisualStylesTests.cs
@@ -814,6 +814,32 @@ public void ButtonDarkModeAdapter_InteractionPaintStateStartsColorAnimation()
Assert.True(animator.IsRunning);
}
+ [WinFormsFact]
+ public void ButtonDarkModeAdapter_InheritedBackColor_UsesThemeStateColorInNet11()
+ {
+ using Panel parent = new() { BackColor = Color.Red };
+ using Button button = new()
+ {
+ FlatStyle = FlatStyle.Standard,
+ VisualStylesMode = VisualStylesMode.Net11
+ };
+ parent.Controls.Add(button);
+ ButtonInternal.ButtonDarkModeAdapter adapter = new(button);
+ dynamic accessor = adapter.TestAccessor.Dynamic;
+ ModernButtonDarkModeRenderer neutralRenderer = new()
+ {
+ DeviceDpi = button.DeviceDpi,
+ FlatAppearance = button.FlatAppearance
+ };
+
+ Color actual = (Color)accessor.GetButtonBackColor(VisualStyles.PushButtonState.Normal);
+
+ Assert.Equal(
+ neutralRenderer.GetBackgroundColor(VisualStyles.PushButtonState.Normal, isDefault: false),
+ actual);
+ Assert.False(button.ShouldSerializeBackColor());
+ }
+
public static TheoryData ModernImageLayoutData
{
get
@@ -1276,7 +1302,7 @@ public void ButtonDarkModeAdapter_ExplicitForeColor_IsPreserved()
}
[WinFormsFact]
- public void ButtonDarkModeAdapter_InheritedForeColor_UsesAutomaticContrast()
+ public void ButtonDarkModeAdapter_InheritedForeColor_IsPreservedInNet11()
{
using Panel parent = new() { ForeColor = Color.Red };
using Button button = new()
@@ -1295,7 +1321,7 @@ public void ButtonDarkModeAdapter_InheritedForeColor_UsesAutomaticContrast()
VisualStyles.PushButtonState.Normal,
Color.White);
- Assert.Equal(Color.Black, actual);
+ Assert.Equal(Color.Red, actual);
Assert.False(button.ShouldSerializeForeColor());
}
diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/PopupButtonVisualStylesTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/PopupButtonVisualStylesTests.cs
index d12e609f5c0..fb76d383343 100644
--- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/PopupButtonVisualStylesTests.cs
+++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/PopupButtonVisualStylesTests.cs
@@ -203,6 +203,37 @@ public void AnimatedPopupButtonRenderer_CustomBackColor_DerivesNeutralStateColor
Assert.Equal(PopupButtonColorMath.TowardsContrast(button.BackColor, 0.12f), pressedColor);
}
+ [WinFormsFact]
+ public void AnimatedPopupButtonRenderer_InheritedBackColor_UsesThemeStateColorsInNet11()
+ {
+ using Panel parent = new() { BackColor = Color.Red };
+ using Button button = new()
+ {
+ FlatStyle = FlatStyle.Popup,
+ VisualStylesMode = VisualStylesMode.Net11
+ };
+ parent.Controls.Add(button);
+ using AnimatedPopupButtonRenderer renderer = new(button);
+ ModernButtonDarkModeRenderer neutralRenderer = new()
+ {
+ DeviceDpi = button.DeviceDpi,
+ FlatAppearance = button.FlatAppearance
+ };
+
+ (Color baseColor, Color hoverColor, Color pressedColor) = renderer.GetStateColors();
+
+ Assert.Equal(
+ neutralRenderer.GetBackgroundColor(VisualStyles.PushButtonState.Normal, isDefault: false),
+ baseColor);
+ Assert.Equal(
+ neutralRenderer.GetBackgroundColor(VisualStyles.PushButtonState.Hot, isDefault: false),
+ hoverColor);
+ Assert.Equal(
+ neutralRenderer.GetBackgroundColor(VisualStyles.PushButtonState.Pressed, isDefault: false),
+ pressedColor);
+ Assert.False(button.ShouldSerializeBackColor());
+ }
+
[WinFormsFact]
public void PopupButtonKeyCapRenderer_FocusedDefault_RendersWithoutThrow()
{