diff --git a/src/System.Windows.Forms/PublicAPI.Unshipped.txt b/src/System.Windows.Forms/PublicAPI.Unshipped.txt
index fd3fe1e230a..70f934d430e 100644
--- a/src/System.Windows.Forms/PublicAPI.Unshipped.txt
+++ b/src/System.Windows.Forms/PublicAPI.Unshipped.txt
@@ -101,6 +101,7 @@ override System.Windows.Forms.RadioButton.OnPaint(System.Windows.Forms.PaintEven
override System.Windows.Forms.RadioButton.OnSystemColorsChanged(System.EventArgs! e) -> void
override System.Windows.Forms.RadioButton.OnVisualStylesModeChanged(System.EventArgs! e) -> void
override System.Windows.Forms.UpDownBase.OnVisualStylesModeChanged(System.EventArgs! e) -> void
+override System.Windows.Forms.ToolStripControlHost.OnOwnerChanged(System.EventArgs! e) -> void
static System.Windows.Forms.Application.DefaultVisualStylesMode.get -> System.Windows.Forms.VisualStylesMode
static System.Windows.Forms.Application.SetDefaultVisualStylesMode(System.Windows.Forms.VisualStylesMode styleSetting) -> void
virtual System.Windows.Forms.Control.DefaultVisualStylesMode.get -> System.Windows.Forms.VisualStylesMode
diff --git a/src/System.Windows.Forms/System/Windows/Forms/Control.VisualStylesMode.Docs.cs b/src/System.Windows.Forms/System/Windows/Forms/Control.VisualStylesMode.Docs.cs
index 4354c55bc36..7d64a502591 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Control.VisualStylesMode.Docs.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Control.VisualStylesMode.Docs.cs
@@ -27,6 +27,9 @@ public partial class Control
/// shrink slightly. Prefer or for adaptive layouts.
///
///
+ /// This setting is not applied to controls hosted through .
+ ///
+ ///
/// High Contrast resolves the effective mode to classic rendering. See the
///
/// .NET 11 VisualStyles layout guidance for migration patterns.
diff --git a/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripControlHost.cs b/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripControlHost.cs
index 7842c46d9ed..ea629788291 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripControlHost.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/Controls/ToolStrips/ToolStripControlHost.cs
@@ -17,6 +17,9 @@ public partial class ToolStripControlHost : ToolStripItem
private int _suspendSyncSizeCount;
private ContentAlignment _controlAlign = ContentAlignment.MiddleCenter;
private bool _inSetVisibleCore;
+ private bool _isUpdatingHostedControlVisualStylesMode;
+ private bool _hostedControlVisualStylesModeForced;
+ private VisualStylesMode _hostedControlVisualStylesModeBeforeForce = VisualStylesMode.Inherit;
internal static readonly object s_gotFocusEvent = new();
internal static readonly object s_lostFocusEvent = new();
@@ -576,6 +579,16 @@ private void HandleResize(object? sender, EventArgs e)
private void HandleTextChanged(object? sender, EventArgs e) => OnTextChanged(e);
+ private void HandleVisualStylesModeChanged(object? sender, EventArgs e)
+ {
+ if (_isUpdatingHostedControlVisualStylesMode)
+ {
+ return;
+ }
+
+ ApplyHostedControlVisualStylesModePolicy();
+ }
+
private void HandleControlVisibleChanged(object? sender, EventArgs e)
{
// check the STATE_VISIBLE flag rather than using Control.Visible.
@@ -684,6 +697,8 @@ protected override void OnParentChanged(ToolStrip? oldParent, ToolStrip? newPare
{
if (oldParent is not null && Owner is null && newParent is null && _control is not null)
{
+ RestoreHostedControlVisualStylesMode();
+
// if we've really been removed from the item collection,
// politely remove ourselves from the control collection
ReadOnlyControlCollection? oldControlCollection
@@ -698,6 +713,20 @@ protected override void OnParentChanged(ToolStrip? oldParent, ToolStrip? newPare
base.OnParentChanged(oldParent, newParent);
}
+ protected override void OnOwnerChanged(EventArgs e)
+ {
+ base.OnOwnerChanged(e);
+
+ if (Owner is null)
+ {
+ RestoreHostedControlVisualStylesMode();
+ }
+ else
+ {
+ ApplyHostedControlVisualStylesModePolicy();
+ }
+ }
+
///
/// The events from the hosted control are subscribed here.
/// Override to add/prevent syncing of control events.
@@ -739,6 +768,7 @@ protected virtual void OnSubscribeControlEvents(Control? control)
control.RightToLeftChanged += HandleRightToLeftChanged;
control.TextChanged += HandleTextChanged;
control.VisibleChanged += HandleControlVisibleChanged;
+ control.VisualStylesModeChanged += HandleVisualStylesModeChanged;
control.Validating += HandleValidating;
control.Validated += HandleValidated;
}
@@ -784,6 +814,7 @@ protected virtual void OnUnsubscribeControlEvents(Control? control)
control.RightToLeftChanged -= HandleRightToLeftChanged;
control.TextChanged -= HandleTextChanged;
control.VisibleChanged -= HandleControlVisibleChanged;
+ control.VisualStylesModeChanged -= HandleVisualStylesModeChanged;
control.Validating -= HandleValidating;
control.Validated -= HandleValidated;
}
@@ -803,6 +834,52 @@ private void SyncControlParent()
{
ReadOnlyControlCollection? newControls = GetControlCollection(ParentInternal);
newControls?.AddInternal(_control);
+ ApplyHostedControlVisualStylesModePolicy();
+ }
+
+ private bool ShouldForceHostedControlClassicVisualStylesMode()
+ => Owner is not null;
+
+ private void ApplyHostedControlVisualStylesModePolicy()
+ {
+ if (_control is null || !ShouldForceHostedControlClassicVisualStylesMode())
+ {
+ return;
+ }
+
+ VisualStylesMode mode = _control.VisualStylesMode;
+ if (mode is VisualStylesMode.Classic or VisualStylesMode.Disabled)
+ {
+ return;
+ }
+
+ _hostedControlVisualStylesModeBeforeForce = mode;
+ _hostedControlVisualStylesModeForced = true;
+ UpdateHostedControlVisualStylesMode(VisualStylesMode.Classic);
+ }
+
+ private void RestoreHostedControlVisualStylesMode()
+ {
+ if (!_hostedControlVisualStylesModeForced || _control is null)
+ {
+ return;
+ }
+
+ UpdateHostedControlVisualStylesMode(_hostedControlVisualStylesModeBeforeForce);
+ _hostedControlVisualStylesModeForced = false;
+ }
+
+ private void UpdateHostedControlVisualStylesMode(VisualStylesMode mode)
+ {
+ _isUpdatingHostedControlVisualStylesMode = true;
+ try
+ {
+ _control.VisualStylesMode = mode;
+ }
+ finally
+ {
+ _isUpdatingHostedControlVisualStylesMode = false;
+ }
}
protected virtual void OnHostedControlResize(EventArgs e)
diff --git a/src/System.Windows.Forms/System/Windows/Forms/VisualStylesMode.cs b/src/System.Windows.Forms/System/Windows/Forms/VisualStylesMode.cs
index e38e19d9d9b..a75eedaab2d 100644
--- a/src/System.Windows.Forms/System/Windows/Forms/VisualStylesMode.cs
+++ b/src/System.Windows.Forms/System/Windows/Forms/VisualStylesMode.cs
@@ -56,6 +56,9 @@ public enum VisualStylesMode : short
/// Controls opt into the .NET 11 rendering changes they support. For example, support for
/// depends on the control and its current state.
///
+ ///
+ /// For controls hosted through , this mode is not applied.
+ ///
///
Net11 = 2,
diff --git a/src/test/unit/System.Windows.Forms/System/Windows/Forms/ToolStripControlHostTests.cs b/src/test/unit/System.Windows.Forms/System/Windows/Forms/ToolStripControlHostTests.cs
index e982f3a6d87..d48787dd54a 100644
--- a/src/test/unit/System.Windows.Forms/System/Windows/Forms/ToolStripControlHostTests.cs
+++ b/src/test/unit/System.Windows.Forms/System/Windows/Forms/ToolStripControlHostTests.cs
@@ -4557,6 +4557,52 @@ public void ToolStripControlHost_SetVisibleCore_InvokeWithHandler_CallsVisibleCh
Assert.Equal(2, callCount);
}
+ [WinFormsFact]
+ public void ToolStripControlHost_HostedControlVisualStylesMode_Net11_IsForcedToClassic()
+ {
+ using Control control = new()
+ {
+ VisualStylesMode = VisualStylesMode.Net11
+ };
+ using ToolStripControlHost host = new(control);
+ using ToolStrip toolStrip = new();
+
+ toolStrip.Items.Add(host);
+
+ Assert.Equal(VisualStylesMode.Classic, control.VisualStylesMode);
+ }
+
+ [WinFormsFact]
+ public void ToolStripControlHost_HostedControlVisualStylesMode_SetToNet11WhileHosted_RemainsClassic()
+ {
+ using Control control = new();
+ using ToolStripControlHost host = new(control);
+ using ToolStrip toolStrip = new();
+
+ toolStrip.Items.Add(host);
+ control.VisualStylesMode = VisualStylesMode.Net11;
+
+ Assert.Equal(VisualStylesMode.Classic, control.VisualStylesMode);
+ }
+
+ [WinFormsFact]
+ public void ToolStripControlHost_HostedControlVisualStylesMode_RemovingHost_RestoresRequestedMode()
+ {
+ using Control control = new()
+ {
+ VisualStylesMode = VisualStylesMode.Net11
+ };
+ using ToolStripControlHost host = new(control);
+ using ToolStrip toolStrip = new();
+
+ toolStrip.Items.Add(host);
+ Assert.Equal(VisualStylesMode.Classic, control.VisualStylesMode);
+
+ toolStrip.Items.Remove(host);
+
+ Assert.Equal(VisualStylesMode.Net11, control.VisualStylesMode);
+ }
+
private class SubControl : Control
{
public new void CreateControl() => base.CreateControl();