美好的一天!
我正在编写.vsix来将旧控件替换为新控件。我有designerHost,它是当前的设计器实例。然后我开始像这样转换:
foreach (OldCombo oldCmbx in OldCmbxs())
{
...
NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx;
...
newCmbx.Visible = oldCmbx.Visible;
...
designerHost.DestroyComponent(oldCmbx);
}
-oldCmbx
始终为Visible=true
,无论它如何在designer.cs文件中编写。我总是在创建Visible=true
newCmbx。如果我强制newCmbx为Visible=false
,那么设计器在转换后不显示newCmbx,但是visible属性仍然是true,因此Visible属性绝对不是我正在搜索的内容。那么如何在designer.cs中强制newCmbx为Visible=false
?
答案 0 :(得分:1)
在深入研究.NET源代码后,我发现ControlDesigner
是Visible
的{{1}}属性,因此Control
将序列化/反序列化。与Control的实际InitializeComponent
属性有很大关系。
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);
}
...
}
的{{1}}始终为descriptor.ShouldSerializeValue(component)
。
Control.Visible
财产:
false
Designer.Visible
的{{1}}实际private bool Visible
{
get
{
return (bool) base.ShadowProperties["Visible"];
}
set
{
base.ShadowProperties["Visible"] = value;
}
}
属性被设计师的Designer.PreFilterProperties()
属性所遮蔽。
现在,当初始化设计器时(在我创建组件Visible
时发生的代码中)Control
总是Visible
。
为什么会这样?因为designerHost.CreateComponent
的{{1}}属性用于绘制控件(在设计器表面上)。如果我设置newCmbx.Visible
它只是从设计图面消失(但仍然从设计器的true
属性序列化) - 这很糟糕,所以通过设计Visible
类,Control
1}}被实例化,它始终是newCmbx.Visible = false
,因此它可以在设计图面上可见。 Visible
属性中的任何后续更改都会影响设计器的Control
属性,而不是Control本身(在Designer模式下工作的上下文中)。
所以,我需要解决这个问题的是设计师的Control
属性。
正确的代码如下所示:
Visible