在挖掘 .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);
}