Here's a rough "skeleton" of what the
beginnings of a style manager for WinForms might look like:
public static class VisualStyleManager
{
public static Dictionary<string, VisualStyle> StyleDictionary { set; get; }
public static void AddStyle(string name, Control control)
{
StyleDictionary.Add(name, new VisualStyle(control));
}
public static void ApplyStyle(string stylename, Control control)
{
VisualStyle style;
if(StyleDictionary.TryGetValue(stylename, out vs)
{
control.BackColor = vs.BackColor;
control ForeColor = vs.ForeColor;
control.Font = vs.Font;
}
}
}
public class VisualStyle
{
public Color CBackColor { set; get; }
public Color CForeColor { set; get; }
public Font CFont {set; get; }
public VisualStyle(Control control)
{
CBackColor = control.BackColor;
CForeColor = control.ForeColor;
CFont = control.Font;
}
}
Here's how it might be used:
private void SetAllFormButtons(Form form, button abutton)
{
VisualStyleManager.AddStyle("ButtonStyle1", button1);
foreach (var btn in this.GetControlsByType<Button>())
{
if (btn != button1)
{
VisualStyleManager.ApplyStyle("ButtonStyle1", btn);
}
}
}
This makes use of an extension Method:
public static class ControlExtensions
{
public static IEnumerable<Control> GetControlsByType<T>(this Control control)
{
Stack<Control> stack = new Stack<Control>();
stack.Push(control);
while (stack.Any())
{
Control nextcontrol = stack.Pop();
foreach (Control childControl in nextcontrol.Controls)
{
stack.Push(childControl);
}
if (nextcontrol is T) yield return nextcontrol;
}
}
}
Now consider what you are going to have to deal with to make this handle WinForm Control Properties like a Form's 'FormBorderStyle, or a Button's FlatStyle, and FlatAppearance Properties; these Properties are not exposed when you cast these Controls to their Control base Type.
For every unique Control Type's Property, you will have to handle that as a special case. However, there are other ways, making heavy use of 'Reflection, to do this. And, you can take the "skeleton" here and sub-class VisualStyle to handle other Control Types with "special requirements."
By now, you may have figured out that to get anything substantial going with theming involves (probably) a lot of work on your part. While doing this may improve your design skills and knowledge of WinForms internals, if you are at a relatively early phase in studying and using WinForms and C#, I suggest you do not take on trying to write a full-featured theme facility.
There are other strategies you could pursue: such as, displaying a Property Browser at run-time to let the user edit colors, fonts, etc. Let's say User1 edited the BackColor of any one Button; you could get a notification of that event and then set all the other Buttons to use that same BackColor.