Reputation: 2817
Good day!
I'm writing a .vsix to replace old controls to new ones. I have designerHost which is the current designer instance. Then I start converting like this:
foreach (OldCombo oldCmbx in OldCmbxs())
{
...
NewCombo newCmbx = designerHost.CreateComponent(NewComboType, oldcmbx.Name) as NewCmbx;
...
newCmbx.Visible = oldCmbx.Visible;
...
designerHost.DestroyComponent(oldCmbx);
}
The thing is -oldCmbx
is always Visible=true
, no matter how it's written in the designer.cs file. I'm always creating Visible=true
newCmbx's. If I force newCmbx to be Visible=false
, then designer doesn't show newCmbx after the conversion, but the visible property is still true, so Visible property is definitely not what I'm searching for. So how can I force newCmbx's to be Visible=false
in designer.cs?
Upvotes: 3
Views: 368
Reputation: 2817
After digging through .NET source code I've found that ControlDesigner
is shadowing Visible
property of the Control
, so what is going to be serialized/deserialized in InitializeComponent
is far related from actual Visible
property of Control.
Designer.Visible
property is initialized like this:
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)
for Control.Visible
is always false
in case of newly created control.
Designer.Visible
property:
private bool Visible
{
get
{
return (bool) base.ShadowProperties["Visible"];
}
set
{
base.ShadowProperties["Visible"] = value;
}
}
In the Designer.PreFilterProperties()
actual Visible
property of the Control
is shadowed by Visible
property of the designer.
Now, when the designer is initialized(in my code that's happening when I'm creating component designerHost.CreateComponent
) newCmbx.Visible
is always true
.
Why it is so? Because Visible
property of the Control
is used in painting of the control(on the designer surface as well). If I set newCmbx.Visible = false
it just disappears from the design surface (but still serializes from the Visible
property of the designer) - that's bad, so by design of the Control
class, when Control
is instantiated, it is always Visible
so that it could be visible on the design surface. Any subsequent changes in Visible
property influence Visible
property of the designer, not Control itself (in the context of working in Designer mode).
So, what I need in order to solve that problem is Visible
property of the designer.
Correct code looks like this:
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);
}
Upvotes: 1