How can I know the name of of a System.ComponentModel.Component AT RUN-TIME?

AlexCode

Senior Contributor
Joined
Jul 7, 2003
Messages
931
Location
Portugal
Right now I'm having another problem with Components...
How do I know their name at run-time??

We can set and see their name at design-time on the property grid, but they have no run-time accessible property...

Thanks in advance,

Alex :p
 
Unfortunately, this is the basic situation: at run time components do not have a name.

Controls have a Name property which stores the name in memory during runtime. The designer uses the same name for both the identifier used in code and the Name property, however if you don't use the designer it is very possible for your identifier and your Name to differ. The two are generally, but not necessarily, the same.

Components do not have a Name property. The name you enter into the designer only determines the identifier to be used in code. The name you put into the designer does not exists in the jitted code. It essentially becomes nothing more than a memory offset.


Depending on your needs, the best solution will vary, but something like this might suit your needs:
Visual Basic:
Dim Franky As Component 'At some point assign a reference
Dim Jules As Component 'At some point assign a reference
 
Public Function NameOf(Item As Component) As String
    If Item Is Franky Then Return "Franky"
    If Item Is Jules Then Return "Jules"
End Function
 
'Example:
MessageBox.Show (NameOf(Jules))
Excuse my very rusty C#
Visual Basic:
System.ComponentModel.Component Franky; //At some point assign a reference
System.ComponentModel.Component Jules; //At some point assign a reference
 
String NameOf(System.ComponentModel.Component Item) {
    if (Item = Franky) return "Franky";
    if (Item = Jules) return "Jules";
}
 
//Example
MessageBox.Show(NameOf(Jules));
 
Hi... many thanks for your reply.

I already managed to get the name of a component:

C#:
using System.Reflection;

            FieldInfo[] fields =
this.GetType().GetFields(BindingFlags.DeclaredOnly | BindingFlags.NonPublic
| BindingFlags.Public | BindingFlags.Instance);
            foreach(FieldInfo field in fields) {
                if (field.GetValue(this) is [The component type we're looking for]) 
                    Console.WriteLine(field.Name);
            }

The problem with this approach is that it returns the correct name but with a underscore first. Someting like: _Component1 for a component named Component1 at design-time.

We can safelly remove the underscore tho, cause this is a generic behaviour for all components.

Again, thank for your reply.

Alex :p
 
Well, you asked the question, but I learned something. Hmm...

Reflection often escapes my attention. When I think of run-time, I think of the compiled code like you would have in C++ where all that metadata simply doesn't exist.
 
I use Reflection a lot...

There's another thing, that uses Reflection, and that is related to this thread, that's getting a control by its name instead of looping thru the Controls array.
And this also works for components... where u don't have an array to loop...

Visual Basic:
    Shared Function FindObject(ByVal ParentControl As Object, ByVal Name As String) As Object
        Dim propInfo As System.Reflection.PropertyInfo

        If TypeOf ParentControl Is Control Then
            propInfo = ParentControl.GetType().GetProperty( _
                Name, _
                System.Reflection.BindingFlags.IgnoreCase Or _
                    System.Reflection.BindingFlags.Instance Or _
                        System.Reflection.BindingFlags.NonPublic Or _
                            System.Reflection.BindingFlags.Public)

            If Not propInfo Is Nothing Then
                Dim value As Object = propInfo.GetValue(ParentControl, Nothing)
                Return value
            End If
        End If

        Return Nothing
    End Function

Hope u enjoy...

Alex :p
 
Sorry to jump in with a question mid-thread, but reflection is slow and indexed loops are fast. Have you done any comparissions that show this is faster?
 
bri189a said:
Sorry to jump in with a question mid-thread, but reflection is slow and indexed loops are fast. Have you done any comparissions that show this is faster?

Hi...
I made some comparisons and I'll explain my preference on Remoting.

No doubt, if you imagine a Form with come controls, it's faster to just loop thru them and find the one we're looking for but, if we have a more complex scenario, like a Form with multiple container components (like TabControls, Panels and so on...) we'll have to evaluate the Controls property of every control if it has any child and then loop thru the child controls...

On that code I gave you guys, the ParentControl argument may be the Form and it will return the control by name even if it's inside any container.
Another thing... that code can return System.ComponentModel.Components by name which you can't get any other way at run-time.

So, for the sake of code maintenance and simplicity, I decided to use the only method that could provide me all the functionality I need.

Best regards,
Alex :p
 
Good point; wasn't doubting your methods, just trying to understand the reasoning. Out of curiousity how did the comparissions turn out? I'm interested to see exactly where the cut off would be - where the axis' cross between recursively going through child controls versus using reflection as you said...the x axis being time, and the y axis being number of controls.
 
Hi...

I'm sorry but I can't give you that answer just because I didn't actually benchmarked it.
Like I said, in my scenario, looping thru the child controls wasn't an option, so I didn't have much choice.

You can do it yourself tho...
Go and add some controls to your Form... don't forget to nest controls inside Tabs and Panels, also Panels inside Panels and complex scenarios like this.

Then test...

My prediction is that for plain child controls search Reflection will be slower... but when it comes to nested controls, looping will take more time, and Reflection will take exactly the same time.
No matter where the control is, Reflection will take allways the same time.

Alex :p
 
Back
Top