winforms question
-
hi all, I'm having a bit of an issue here and maybe one of you guys can help me out . I'm looking for a way to return all COMPONENTS in a form during run-time, and i mean components including all controls , menu's, custom controls etc. As you all now a control is a component but a component is not a control. You will probably think that i'm somesort of idiot , but i'm not (at least i think i'm not), and i've tried every possible way to reach my goal: 1) tried to convert the form as container -> didn't work 2) adding the component that needs to perform above actions and using it's own container as componentcollection holder doesn't work, bcause the container returned is the component itself. 3) returning a menu's container -> doesn't work -> it always returns nothing batmike2000
-
hi all, I'm having a bit of an issue here and maybe one of you guys can help me out . I'm looking for a way to return all COMPONENTS in a form during run-time, and i mean components including all controls , menu's, custom controls etc. As you all now a control is a component but a component is not a control. You will probably think that i'm somesort of idiot , but i'm not (at least i think i'm not), and i've tried every possible way to reach my goal: 1) tried to convert the form as container -> didn't work 2) adding the component that needs to perform above actions and using it's own container as componentcollection holder doesn't work, bcause the container returned is the component itself. 3) returning a menu's container -> doesn't work -> it always returns nothing batmike2000
Can you do something like this?
List<IComponent> components = new List<IComponent>();
foreach (object obj in myForm.Controls)
if (obj is IComponent)
components.Add(obj as IComponent);You might have to do it recursively though.
Last modified: Wednesday, May 31, 2006 12:24:40 PM --
-
Can you do something like this?
List<IComponent> components = new List<IComponent>();
foreach (object obj in myForm.Controls)
if (obj is IComponent)
components.Add(obj as IComponent);You might have to do it recursively though.
Last modified: Wednesday, May 31, 2006 12:24:40 PM --
That won't work because, as the original question mentioned, all controls are components but not vice versa (Control derives from Component). Components are not in a form's Control tree. Josh
-
That won't work because, as the original question mentioned, all controls are components but not vice versa (Control derives from Component). Components are not in a form's Control tree. Josh
How about reflection then? You can do a GetMembers() on the form's Type and look for fields. See if that field type is an implementation of IComponent, and add it to the list.
List<IComponent> components = new List<IComponent>();
foreach (MemberInfo mi in this.GetType().GetMembers()) {
if (mi.MemberType == MemberTypes.Field) {
if (mi.DeclaringType.GetInterface("IComponent") != null) {
FieldInfo fi = mi as FieldInfo;
components.Add((IComponent)fi.GetValue(this));
}
}
}I haven't tested this code, but it should be pretty close.
Last modified: Wednesday, May 31, 2006 12:25:05 PM --
-
How about reflection then? You can do a GetMembers() on the form's Type and look for fields. See if that field type is an implementation of IComponent, and add it to the list.
List<IComponent> components = new List<IComponent>();
foreach (MemberInfo mi in this.GetType().GetMembers()) {
if (mi.MemberType == MemberTypes.Field) {
if (mi.DeclaringType.GetInterface("IComponent") != null) {
FieldInfo fi = mi as FieldInfo;
components.Add((IComponent)fi.GetValue(this));
}
}
}I haven't tested this code, but it should be pretty close.
Last modified: Wednesday, May 31, 2006 12:25:05 PM --
Hi Dustin tnx for the reply, unfortunately it doesn't seem to work. Maybe i should dig in a little deeper, but i don't think this can work because imho components aren't fields . Tnx for the effort anyway. Maybe i shoud try another approach. If I just could get the correct container from my component (ie. the form it's hosted on but then defined as container instead of form). BTW: i'm still using .Net 1.1 and not 2.0, just to avoid confusion. batmike2000
-
How about reflection then? You can do a GetMembers() on the form's Type and look for fields. See if that field type is an implementation of IComponent, and add it to the list.
List<IComponent> components = new List<IComponent>();
foreach (MemberInfo mi in this.GetType().GetMembers()) {
if (mi.MemberType == MemberTypes.Field) {
if (mi.DeclaringType.GetInterface("IComponent") != null) {
FieldInfo fi = mi as FieldInfo;
components.Add((IComponent)fi.GetValue(this));
}
}
}I haven't tested this code, but it should be pretty close.
Last modified: Wednesday, May 31, 2006 12:25:05 PM --
hi guys, i've found the solution: i indeed needed to use reflection but on fieldinfo level
strFormName = param_Form.Name Dim param_Form_type As Type = param_Form.GetType() Dim compFields As FieldInfo() = param_Form_type.GetFields(BindingFlags.Instance Or BindingFlags.NonPublic) For Each fiField As FieldInfo In compFields Dim strCtrl(1) As String strCtrl = ReturnCompName(fiField, param_Form) For Each dr As DataRow In myrs.Rows If strCtrl(0) = dr("SecAuthCtrl_Name") And fiField.FieldType.FullName = dr("SecAuthCtrl_Type") Then Select Case fiField.FieldType.FullName.ToLower Case "System.Windows.Forms.ToolBarButton".ToLower Dim cmp As ToolBarButton = DirectCast(fiField.GetValue(param_Form), ToolBarButton) cmp.Enabled = dr("SecAuthorized_Enabled") cmp.Visible = dr("SecAuthorized_Visible") Case "System.Windows.Forms.MenuItem".ToLower Dim cmp As MenuItem = DirectCast(fiField.GetValue(param_Form), MenuItem) cmp.Enabled = dr("SecAuthorized_Enabled") cmp.Visible = dr("SecAuthorized_Visible") Case Else End Select End If Next Next
this works now, tnx again for your effort batmike2000 -
hi guys, i've found the solution: i indeed needed to use reflection but on fieldinfo level
strFormName = param_Form.Name Dim param_Form_type As Type = param_Form.GetType() Dim compFields As FieldInfo() = param_Form_type.GetFields(BindingFlags.Instance Or BindingFlags.NonPublic) For Each fiField As FieldInfo In compFields Dim strCtrl(1) As String strCtrl = ReturnCompName(fiField, param_Form) For Each dr As DataRow In myrs.Rows If strCtrl(0) = dr("SecAuthCtrl_Name") And fiField.FieldType.FullName = dr("SecAuthCtrl_Type") Then Select Case fiField.FieldType.FullName.ToLower Case "System.Windows.Forms.ToolBarButton".ToLower Dim cmp As ToolBarButton = DirectCast(fiField.GetValue(param_Form), ToolBarButton) cmp.Enabled = dr("SecAuthorized_Enabled") cmp.Visible = dr("SecAuthorized_Visible") Case "System.Windows.Forms.MenuItem".ToLower Dim cmp As MenuItem = DirectCast(fiField.GetValue(param_Form), MenuItem) cmp.Enabled = dr("SecAuthorized_Enabled") cmp.Visible = dr("SecAuthorized_Visible") Case Else End Select End If Next Next
this works now, tnx again for your effort batmike2000Great! I'm glad you found the answer. www.logifusion.com