The Problem:
How to detect a case where components field of UserControl or Form is null?
A null value indicates that no components are hosted in the Form/UserControl.
The Solution:
We need to check whether the specified Control/Form hosts at least one Component, excluding components defined in base class.
The challenge is to do it while the object doesn't exist yet, actually it happens when the class file (*.Desinger.cs) is built by the desinger.
The information was fetched using reflection from the Designer manager class IDesignerSerializationManager, it manages stack of desinger code statements.
In this stack we can find statements declaring the class member fields (the declaration of member fields section can be found in the end of the *.Designer.cs file.), if there is member field inherits from Component we have at Component in the Form/Control.
Code Example:
internal static bool IsLocalComponentsExist(IDesignerSerializationManager manager)
{
// get the contextStack member of the IDesignerSerializationManager
FieldInfo contextStackField = typeof(ContextStack).GetField (CONTEXT_STACK_MEMBER, BindingFlags.NonPublic | BindingFlags.Instance);
if (contextStackField != null)
{
// get the designer stack collection
ArrayList contextStack = (ArrayList)contextStackField.GetValue(manager.Context);
Type componentType = typeof(Component);
// search for the CodeTypeDeclaration to find the localy defined Components
foreach (object obj in contextStack)
{
if (obj is CodeTypeDeclaration)
{
CodeTypeDeclaration codeTypeDeclaration = (CodeTypeDeclaration)obj;
foreach (CodeMemberField memberField in codeTypeDeclaration.Members)
{
// get the Form/Control member field type
Type memberFieldType = Type.GetType(memberField.Type.BaseType);
// check if the memberFieldType is a Component
if (componentType.IsAssignableFrom(memberFieldType))
{
// if at least one component exist we can return.
return true;
}
}
}
}
}
return false;
}
Enjoy
How to detect a case where components field of UserControl or Form is null?
A null value indicates that no components are hosted in the Form/UserControl.
The Solution:
We need to check whether the specified Control/Form hosts at least one Component, excluding components defined in base class.
The challenge is to do it while the object doesn't exist yet, actually it happens when the class file (*.Desinger.cs) is built by the desinger.
The information was fetched using reflection from the Designer manager class IDesignerSerializationManager, it manages stack of desinger code statements.
In this stack we can find statements declaring the class member fields (the declaration of member fields section can be found in the end of the *.Designer.cs file.), if there is member field inherits from Component we have at Component in the Form/Control.
Code Example:
internal static bool IsLocalComponentsExist(IDesignerSerializationManager manager)
{
// get the contextStack member of the IDesignerSerializationManager
FieldInfo contextStackField = typeof(ContextStack).GetField (CONTEXT_STACK_MEMBER, BindingFlags.NonPublic | BindingFlags.Instance);
if (contextStackField != null)
{
// get the designer stack collection
ArrayList contextStack = (ArrayList)contextStackField.GetValue(manager.Context);
Type componentType = typeof(Component);
// search for the CodeTypeDeclaration to find the localy defined Components
foreach (object obj in contextStack)
{
if (obj is CodeTypeDeclaration)
{
CodeTypeDeclaration codeTypeDeclaration = (CodeTypeDeclaration)obj;
foreach (CodeMemberField memberField in codeTypeDeclaration.Members)
{
// get the Form/Control member field type
Type memberFieldType = Type.GetType(memberField.Type.BaseType);
// check if the memberFieldType is a Component
if (componentType.IsAssignableFrom(memberFieldType))
{
// if at least one component exist we can return.
return true;
}
}
}
}
}
return false;
}
Enjoy