C# DesignerHost无法创建Visible=false的控件

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

你好

我正在编写一个.vsix来将旧控件替换为新控件。我有designerHost,它是当前设计器实例。然后我开始这样转换:

 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()
actual
Visible
控件的
属性被设计器的
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);
}