我正在寻找一种方法来为我的C.NET Windows应用程序中不同类型的控件设置我自己的默认属性值。默认属性值应“重写”控件的现有默认值,但仍可以通过在设计器中显式设置属性值来“重写”。
这是为了简化当客户(或我自己)第10次改变主意时更改控件默认外观/行为的过程。这尤其与控制有关,比如
DataGridView
或第三方控制,其中有吨布局相关的财产维护。
我知道创建继承的控件并使用
DefaultValue
属性,但这不是我要寻找的解决方案
有几个原因:
-
要继承我要为其指定自定义属性的每种类型的控件都是一件很麻烦的事情,更不用说覆盖/隐藏属性和设置defaultvalue属性了。
-
我不能再使用标准的.NET控件,但必须使用继承的控件。
-
继承的控件的数量随着时间的推移而增加,并使工具箱变得混乱。
-
我自己或项目中的其他开发人员在匆忙中忘记使用新的固有类型,从而导致控件的行为/外观不正确。
我就是这样想的:
-
例1:
一
数据表格控件
默认情况下具有背景色
SystemColors.Window
. 我自己设定
默认值为
Color.Blue
(如何)
太可恶了!)。在设计器中,
使用默认背景色,
即背景色未设置
在.designer.cs文件中显式。
在运行应用程序时,会执行一部分代码,从而使网格
蓝色,由我指定。
-
例2:
相同的背景色
数据表格控件
设置为
Color.Red
在设计师中。这个
覆盖我自己的蓝色默认值,显示红色背景
在网格中,包括设计时和运行时。
解决方案
我的解决方案是使用反射来检查
默认值
属性,由建议
Daniel Brückner
.
我重复一遍窗体上的所有控件,调用
SetDefaultValues
对于每个控件。对于要设置的每个属性值,我调用
SetValue
方法,它确保只设置未更改其默认值的属性。
不过,这种方法有一个缺陷
. 已在设计器中显式设置但与默认值没有差异的属性将被覆盖。
赋值
方法。
void SetDefaultValues(Control control)
{
if (control is DataGridView)
{
SetValue(control, "BackColor", Color.Blue);
}
else if (control is TextBox)
{
// etc.
}
}
private static void SetValue(object control, string propertyName, object newValue)
{
System.Reflection.PropertyInfo prop = control.GetType().GetProperty(propertyName);
if (prop == null)
{
throw new ArgumentException(string.Format(
"Specified property \"{0}\" does not exist on type \"{1}\".", prop.Name, control.GetType().FullName),
"propertyName");
}
bool defaultValueFound = false;
object defaultValue = null;
foreach (object attr in prop.GetCustomAttributes(true))
{
if (attr is DefaultValueAttribute)
{
defaultValue = ((DefaultValueAttribute)attr).Value;
defaultValueFound = true;
break;
}
}
if (!defaultValueFound && prop.PropertyType.IsValueType)
{
// Get default value for value types if no default value was specified by attributes:
defaultValue = Activator.CreateInstance(prop.PropertyType);
}
if (defaultValue == null || defaultValue.Equals(prop.GetValue(control, null)))
{
// If default value matches current value, set new value:
prop.SetValue(control, newValue, null);
}
}