Open ainwood opened 2 years ago
This is how I solved it.
private delegate void safeSetSkinColourDelegate(Control control, MaterialSkinManager manager, ColorScheme newScheme);
public static void SafeSetSkinColour(this Control control, MaterialSkinManager manager, ColorScheme newScheme)
{
if (control.InvokeRequired)
{
safeSetSkinColourDelegate _delegate = new safeSetSkinColourDelegate(SafeSetSkinColour);
control.Invoke(_delegate, new object[] { control, manager, newScheme });
}
else
{
manager.ColorScheme = newScheme;
control.Refresh();
}
}
Called by:
MainForm.SafeSetSkinColour(ManagerInstance, new MaterialSkin.ColorScheme(Primary, DarkPrimary, LightPrimary, Accent, TextShade));
Edit - based on this, the behaviour is arguably not a bug. But inconsistent behaviour amongst controls.
I wanted the users to be able to change the color scheme. I have a watcher that monitors the settings in a database, and if they change the values, the watcher kicks-off a background worker that applies the new theme.
This worked great - changed the MaterialForm colors, MaterialCard colors and MaterialButton colors. But I get an InvalidOperationException with the MaterialTabControl.
Note: What is strange is that: When the main form is initially created, the SkinManager is set to a default blue theme.
SkinManagerInstance = MaterialSkinManager.Instance; SkinManagerInstance.AddFormToManage(this); SkinManagerInstance.Theme = MaterialSkinManager.Themes.LIGHT; SkinManagerInstance.ColorScheme = new ColorScheme(Primary.Blue800, Primary.Blue900, Primary.Blue500, Accent.LightBlue200, TextShade.WHITE);
I then create my application model, which sets-up the watcher. This retrieves the initial theme values from the database, and kicks-off the worker that changes the theme. This first change appears to work OK.
It is only subsequent to this that a change in the values causes the cross-thread issue.
'eTestApp.exe' (CLR v4.0.30319: eTestApp.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.DirectoryServices.Protocols\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.DirectoryServices.Protocols.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. New theme detected. //<=Watcher loading the theme for the first time. MaterialSkin.ColorScheme //<=Theme applied, no problem. The thread 0x1a08 has exited with code 0 (0x0). New theme detected. //<=Value changed in database, detected by Watcher. Exception thrown: 'System.InvalidOperationException' in System.Windows.Forms.dll //<=Exception occurs.
Ultimately, I can work-around this by making the changes to the themes when the application isn't running. I just wanted to let people tweak values and see the changes in real-time.