2012-10-31 35 views
3

美好的一天!DesignerHost無法使用Visible = false創建控件

我正在寫一個.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's。如果我強制newCmbx爲Visible=false,那麼設計者在轉換後不會顯示newCmbx,但可見屬性仍然爲true,所以Visible屬性絕對不是我正在尋找的。那麼我怎樣才能在designer.cs中強制newCmbx成爲Visible=false

回答

1

通過.NET源代碼挖後我發現,ControlDesigner被遮蔽的ControlVisible屬性,所以什麼事情序列化/反序列化在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); 
    } 
    ... 
} 

descriptor.ShouldSerializeValue(component)Control.Visible總是false在新創建的控制的情況下。

Designer.Visible屬性:

private bool Visible 
{ 
    get 
    { 
     return (bool) base.ShadowProperties["Visible"]; 
    } 
    set 
    { 
     base.ShadowProperties["Visible"] = value; 
    } 
} 

ControlDesigner.PreFilterProperties()實際Visible屬性是由設計師Visible財產陰影。

現在,當設計師初始化時(在我創建組件designerHost.CreateComponent時發生的代碼中)newCmbx.Visible始終爲true

爲什麼是這樣?因爲ControlVisible屬性用於控件的繪製(也在設計器表面上)。如果我設置了newCmbx.Visible = false,它只是從設計表面消失(但仍然從設計器的Visible序列化) - 這很糟糕,所以通過Control類的設計,當Control被實例化時,它始終是Visible,以便它可以可見在設計表面上。任何後續更改Visible屬性影響Visible設計者的財產,而不是控制自己(在設計師模式下工作的情況下)。

所以,我需要的是爲了解決這個問題是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); 
}