C# DesignerHost无法创建Visible=false的控件
你好 我正在编写一个.vsix来将旧控件替换为新控件。我有designerHost,它是当前设计器实例。然后我开始这样转换:C# DesignerHost无法创建Visible=false的控件,c#,winforms,visual-studio-2010,C#,Winforms,Visual Studio 2010,你好 我正在编写一个.vsix来将旧控件替换为新控件。我有designerHost,它是当前设计器实例。然后我开始这样转换: foreach (OldCombo oldCmbx in OldCmbxs()) { ... NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx; ... newCmbx.Visible = oldC
foreach (OldCombo oldCmbx in OldCmbxs())
{
...
NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx;
...
newCmbx.Visible = oldCmbx.Visible;
...
designerHost.DestroyComponent(oldCmbx);
}
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);
}
...
}
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);
}
问题是,
-oldCmbx
始终是Visible=true
,无论它如何写入designer.cs文件。我总是创建Visible=true
newCmbx。如果我强制newCmbx为Visible=false
,则设计器在转换后不会显示newCmbx,但Visible属性仍然为true,因此Visible属性肯定不是我要搜索的。那么,我如何才能在designer.cs中强制newCmbx的Visible=false
?在挖掘.NET源代码之后,我发现ControlDesigner
正在隐藏控件的Visible
属性,因此,在InitializeComponent
中要序列化/反序列化的内容与控件的实际Visible
属性有很大关系
Designer.Visible
属性初始化如下:
foreach (OldCombo oldCmbx in OldCmbxs())
{
...
NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx;
...
newCmbx.Visible = oldCmbx.Visible;
...
designerHost.DestroyComponent(oldCmbx);
}
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);
}
...
}
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);
}
描述符。对于控件,应序列化值(组件)
。对于新创建的控件,可见的始终为false
Designer.Visible
属性:
private bool Visible
{
get
{
return (bool) base.ShadowProperties["Visible"];
}
set
{
base.ShadowProperties["Visible"] = value;
}
}
在Designer.PreFilterProperties()
actualVisible
控件的属性被设计器的Visible
属性隐藏
现在,当设计器初始化时(在我创建组件时发生的代码中designerHost.CreateComponent
)newCmbx.Visible
总是true
为什么会这样?因为控件的Visible
属性用于控件的绘制(也在设计器表面上)。如果我设置newCmbx.Visible=false
它只是从设计图面消失(但仍然从设计器的Visible
属性序列化)-这很糟糕,因此通过控件
类的设计,当控件
被实例化时,它始终可见
,以便在设计图面上可见。Visible
属性中的任何后续更改都会影响设计器的Visible
属性,而不是控制自身(在设计器模式下工作时)
所以,为了解决这个问题,我需要的是设计器的Visible
属性
正确的代码如下所示:
foreach (OldCombo oldCmbx in OldCmbxs())
{
...
NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx;
...
newCmbx.Visible = oldCmbx.Visible;
...
designerHost.DestroyComponent(oldCmbx);
}
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);
}
...
}
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);
}