Adding user controls at runtime using string

Himo said:
But problem no. 1 here:
From my point of view davearia uses VB .net, that doesn't allow typecasting. Away solution...
Oh you disbelievers..... are there still people out there who don't believe that VB has grown up long time ago!? :p

There is even a second way of type casting. It's the method CType. :cool:
 
davearia said:
IcePlug can you please elaborate just a bit more with your code.

I have a resulting String str which holds the name of the control we are going to create. How exactly am I going to use this to create an instance of this control.

Many thanks in anticipation. :D
I merely converted mutant's C# code to VB.NET. From the looks of it, it creates something from within the assembly that you have to convert to a control, but I won't profess to knowing exactly what it is. :)
 
Here is an equivalent for you:
The DirectCast call will convert the created object into a control for you.
Visual Basic:
Dim ctrlname As String = "WindowsApplication1.myctrl"

Dim asmb As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
Dim ctrl As UserControl = DirectCast(asmb.CreateInstance(ctrlname, False), UserControl)
 
This is all a question of how to use basic reflection, which .NET supports wonderfully. Just a meander thru the System.Reflection namespace should yield answers. The many Assembly.Load* functions should give you an idea of how to access system assemblies.
 
Many thanks for your help.

Here is what I used:
Visual Basic:
Dim ctrlname As String = "ctlMyControl"
Dim asmb As System.Reflection.Assembly = System.Reflection.Assembly.LoadFrom("C:\MyDLL.dll")
Dim ctrl As UserControl = DirectCast(asmb.CreateInstance(ctrlname, False), UserControl)
Me.pnl.Controls.Add(ctrl)

The only thing I needed to change from the code provided was the assembly reference as the reference is a dll outside the current assembly.

Thanks to everyone again you are brilliant.

Thanks, Dave. :D :D :D
 
davearia said:
Thanks to everyone again you are brilliant.
davearia is right. You are all brilliant, and even though self-praise stinks, I am brilliant too :D , BECAUSE: What puzzled me all the time (beside the solution for davearia) was the question, how to create random controls out of the types of the System.Windows.Forms namespace that come similar to davearia's question, for instance out of a table? So all you have is strings. And possibly with Option Strict On. And here is what I elaborated (if sombody is interested), owing to all the hints above:
Visual Basic:
		Dim Asm As [Assembly]
		Dim vType As Type
		Dim Ctrl As Control

		Asm = [Assembly].LoadWithPartialName("System.Windows.Forms")
		vType = Asm.GetType("System.Windows.Forms.TextBox")
		Ctrl = CType(Activator.CreateInstance(vType), Control)
		Ctrl.Name = "myTextBox"
		Me.Controls.Add(Ctrl)
The one and only question left is, how to add an eventhandler to a control, without hardcoding the delegates. I found no method in the reflection namespace that returns an object that could be casted into an eventhandler. But maybe sombody else knows and let us know.

I'd appreciate it. :)
 
There is System.Reflection.EventInfo class. The System.Type class has a method, GetEvents(), which returns an array of EventInfo objects representing each of a certain type's events. How to handle these events without a preexisting delegate is beyond me.
 
To add the event handler like you want:

Visual Basic:
                Dim asm As System.Reflection.Assembly
                't = Type of the object where the event handler procedure is
                'You can use the referenced assembly to get this type: t = asm.GetType("Calss...path")
                Dim t As Type

                Dim c As System.Windows.Forms.Control   'Control reflected

                Dim mymethod As System.Reflection.MethodInfo = t.GetMethod("Procedure Name")
                Dim pEv As System.Reflection.EventInfo = Me.GetType.GetEvent("Click")
                Dim pDel As [Delegate] = [Delegate].CreateDelegate(pEv.EventHandlerType, mymethod)
                pEv.AddEventHandler(c, pDel)

Alex :p
 
Hey, thats cool, thanks a lot. :) :) :)

But there are two minor questions left.

1.)
Visual Basic:
Dim mymethod As System.Reflection.MethodInfo = t.GetMethod("BClick")
This only detects public methods. Even when I extended the line to
Visual Basic:
t.GetMethod("BClick", BindingFlags.NonPublic)
it returned nothing. The method had to be public.

2.)
Visual Basic:
Dim pDel As [Delegate] = [Delegate].CreateDelegate(pEv.EventHandlerType, mymethod)
At that line an exception was thrown. The method has to be static.

Ok, 2.) is not a question; I can live with that, though it might have implications with declaration of variables used in that method, but 1.) is strange. Am I doing something wrong, or is it a bug?
 
Just found out something: When you extend the line to
Visual Basic:
t.GetMethod("BClick", BindingFlags.NonPublic Or BindingFlags.Static)
it also works with private methods - but only if it's static as well.

It's really strange that this methods doesn't return any method that is just private. It HAS to be declared private shared. In this case it doen't matter, because the CreateDelegate methods needs a static one, but in other cases....

Any idea?
 
Back
Top