问题
I'm inside a function that repaints certain controls inside a form, it is implemented as an extension method for the ControlCollection class like this:
void SetColorsCorrespondingToVisualStudioTheme(this Control.ControlCollection controls)
{
foreach (var control in controls)
{
...
Inside this method, the code that sets some GUI properties that are common to a set of controls:
...
if (controlType == typeof(TreeView))
{
((TreeView)control).BorderStyle = BorderStyle.None;
((TreeView)control).BackColor = EditorBackgroundColor;
((TreeView)control).ForeColor = FontColor;
continue;
}
if (controlType == typeof(TextBox))
{
((TextBox)control).BorderStyle = BorderStyle.None;
((TextBox)control).BackColor = EditorBackgroundColor;
((TextBox)control).ForeColor = FontColor;
}
...
I'll like to know if there is a way refactor the code to be reused like:
if (controlType == typeof(TreeView) || controlType == typeof(TextBox))
{
((controlType)control).BorderStyle = BorderStyle.None;
((controlType)control).BackColor = EditorBackgroundColor;
((controlType)control).ForeColor = FontColor;
}
The code above obviously doesn't work because controlType is a variable and not a type but the intention of what I'm trying to do is what matters. I've also tried:
((typeof(controlType))control).B...
The only option I can think of now is to create custom controls for the base types (TreeView, TextBox, etc,) and make all of them implement a common interface so I can use them interchangeably:
...
if (controlType == typeof(TreeView) || controlType == typeof(TextBox))
{
//CustomControl() ñ
ICustomControl newControl = new CustomControl(control);
newControl.BorderStyle = BorderStyle.None;
newControl.BackColor = EditorBackgroundColor;
newControl.ForeColor = FontColor;
}
...
public class CustomTreeView : ICustomControl
{
...
public class CustomTextBox : ICustomControl
{
...
public interface ICustomControl
{
public BorderStyle BorderStyle {get; set;}
public Color BackColor {get; set;}
public Color ForeColor {get; set;}
...
but that (at least in my head) sounds worse than keeping the multiple if's. am I missing another approach you may know to solve this problem?
回答1:
if (control is TreeView || control is TextBox)
{
((Control)control).BorderStyle = BorderStyle.None;
((Control)control).BackColor = EditorBackgroundColor;
((Control)control).ForeColor = FontColor;
}
回答2:
I would probably create a struct to keep the desired values for the properties, and a method that takes a parameter of type Control and apply the style on it:
struct ThemeStyle
{
ThemeStyle(Color backColor, Color foreColor, BorderStyle borderStyle)
{
this.BackColor = backColor;
this.ForeColor = foreColor;
this.BorderStyle = borderStyle;
}
public Color BackColor {get; private set;}
public Color ForeColor {get; private set;}
public BorderStyle BorderStyle {get; private set;}
public void Apply(Control c)
{
c.BackColor = this.BackColor;
switch(typeof(c))
{
case typeof(TreeView):
case typeof(TextBox):
c.BorderStyle = this.BorderStyle;
break;
}
}
}
Note: this code is only a demonstration, written directly here using a cellphone. There might be some mistakes.
Then in your loop all you need to do is call the Apply method with the control.
来源:https://stackoverflow.com/questions/31251750/setting-up-common-properties-to-a-set-controls