在挖掘 .NET 源代码后,我发现这ControlDesigner
是 .NET 的阴影Visible
属性Control
,因此将要序列化/反序列化的内容与ControlInitializeComponent
的实际属性有很大关系。Visible
Designer.Visible
属性初始化如下:
public override void Initialize(IComponent component)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(component.GetType());
PropertyDescriptor descriptor = properties["Visible"];
if (((descriptor == null) || (descriptor.PropertyType != typeof(bool))) || !descriptor.ShouldSerializeValue(component))
{
this.Visible = true;
}
else
{
this.Visible = (bool) descriptor.GetValue(component);
}
...
}
descriptor.ShouldSerializeValue(component)
forControl.Visible
总是false
在新创建的控件的情况下。
Designer.Visible
财产:
private bool Visible
{
get
{
return (bool) base.ShadowProperties["Visible"];
}
set
{
base.ShadowProperties["Visible"] = value;
}
}
在Designer.PreFilterProperties()
实际Visible
属性中被设计者Control
的属性所掩盖。Visible
现在,当设计器被初始化时(在我创建组件时发生的代码中designerHost.CreateComponent
)newCmbx.Visible
总是true
.
为什么会这样?因为Visible
的属性Control
用于绘制控件(在设计器表面上也是如此)。如果我设置newCmbx.Visible = false
它只是从设计表面消失(但仍然从设计器的Visible
属性中序列化) - 这很糟糕,所以通过Control
类的设计,当Control
被实例化时,它总是Visible
可以在设计表面上可见。属性的任何后续更改都会Visible
影响Visible
设计器的属性,而不是 Control 本身(在设计器模式下工作的上下文中)。
所以,为了解决这个问题,我需要的是Visible
设计师的财产。
正确的代码如下所示:
foreach (OldCombo oldCmbx in OldCmbxs())
{
bool _visible = GetVisiblePropThroughReflection(designerHost.GetDesigner(oldCmbx));
...
NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx;
...
SetVisiblePropThroughReflection(designerHost.GetDesigner(newCmbx), _visible);
...
designerHost.DestroyComponent(oldCmbx);
}