.NET ソース コードを掘り下げた後、.NETのControlDesigner
シャドウ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
ます (デザイナー モードでの作業のコンテキストで)。
ですから、その問題を解決するために必要な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);
}