-
Notifications
You must be signed in to change notification settings - Fork 1k
[Dark Mode] Some toolstrip colors don't change when switching color mode #12027
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Calling this from the main thread after switching color modes seems to be a working hack: private void ClearCachedBrushesAndPens()
{
var threadData = (IDictionary<object, object?>) typeof(SystemBrushes).Assembly.GetType("System.Drawing.Gdip")!
.GetProperty("ThreadData", BindingFlags.Static | BindingFlags.NonPublic)!
.GetValue(null)!;
var systemBrushesKey = typeof(SystemBrushes)
.GetField("s_systemBrushesKey", BindingFlags.Static | BindingFlags.NonPublic)!
.GetValue(null)!;
var systemPensKey = typeof(SystemPens)
.GetField("s_systemPensKey", BindingFlags.Static | BindingFlags.NonPublic)!
.GetValue(null)!;
threadData[systemBrushesKey] = null;
threadData[systemPensKey] = null;
} |
@cyanfish, cannot reproduce the issue based on your description as below screenshot. could you please have a check if there have any wrong steps. |
Sorry, the trigger is actually much more obscure than I thought. It seems to be some kind of race condition when calling Specific repro steps with the below code:
But as noted in the code with any kind of delay to the Repro Codeusing Microsoft.Win32;
namespace WinFormsApp1;
static class Program
{
[STAThread]
static void Main()
{
ApplicationConfiguration.Initialize();
#pragma warning disable WFO5001
Application.SetColorMode(SystemColorMode.System);
#pragma warning restore WFO5001
Application.Run(new Form1());
}
}
public class Form1 : Form
{
private static DarkModeManager _dmm;
public Form1()
{
_dmm = new DarkModeManager();
var btn = new Button { Text = "Form2", Location = new Point(0, 50) };
btn.Click += (_, _) => new Form2().Show();
Controls.Add(btn);
}
}
public class Form2 : Form
{
public Form2()
{
var tsc = new ToolStripContainer();
var ts = new ToolStrip();
ts.Items.Add(new ToolStripSplitButton("A"));
ts.Items.Add(new ToolStripSeparator());
ts.Items.Add(new ToolStripSplitButton("B"));
tsc.TopToolStripPanel.Controls.Add(ts);
Controls.Add(tsc);
}
}
public class DarkModeManager
{
private bool? _value;
public DarkModeManager()
{
SystemEvents.UserPreferenceChanged += OnUserPreferenceChanged;
}
private bool ReadDarkMode()
{
try
{
using var key =
Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize");
return Equals(key?.GetValue("AppsUseLightTheme"), 0);
}
catch (Exception)
{
return false;
}
}
private void OnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
var newValue = ReadDarkMode();
if (newValue != _value)
{
_value = newValue;
#pragma warning disable WFO5001
// This does not work:
Application.SetColorMode(newValue ? SystemColorMode.Dark : SystemColorMode.Classic);
// This works:
// Task.Delay(100).ContinueWith(_ =>
// Application.SetColorMode(newValue ? SystemColorMode.Dark : SystemColorMode.Classic));
#pragma warning restore WFO5001
}
}
} |
@cyanfish thanks for your response, yes. the issue can be reproduced with your code as below screenshot. This does not work: This works: |
This issue is now marked as "help wanted", and we’re looking for a community volunteer to work on this issue. If we receive no interest in 180 days, we will close the issue. To learn more about how we handle feature requests, please see our documentation. Happy Coding! |
.NET version
9.0.100-rc.2.24430.10
Did it work in .NET Framework?
No
Did it work in any of the earlier releases of .NET Core or .NET 5+?
Dark mode is a new feature in net9
Issue description
Some toolstrip colors don't change when the SystemColorMode is changed while the app is running, even after re-creating the form. (It works fine when setting the SystemColorMode at app start.)
Correct (when starting the app in dark mode):

Incorrect (when starting the app in light mode, switching to dark mode, and re-creating the form):

I believe the root cause of the issue is here, where there is a static cache of brushes with an index based on the
KnownColor
enum (e.g.KnownColor.ControlText
). I imagine the solution involves purging these caches when the color mode is changed.winforms/src/System.Drawing.Common/src/System/Drawing/SystemBrushes.cs
Line 53 in b6695d6
Also here has a similar problem, though I haven't evaluated if there are further impacts from these static caches.
winforms/src/System.Drawing.Common/src/System/Drawing/SystemPens.cs
Line 54 in b6695d6
Steps to reproduce
Application.SetColorMode(SystemColorMode.Classic)
Application.SetColorMode(SystemColorMode.Dark)
The text was updated successfully, but these errors were encountered: