Opening a specific form with a string

P

Paul Craig

Hi,
I am currently able to open forms given a string variable using the
following code:
Dim strForm As String = "Form1"
Dim theForm As Form
theForm = AppDomain.CurrentDomain.CreateInstanceAndUnwrap _
(Me.GetType.Assembly.GetName.Name, System.String.Concat
_
(Me.GetType.Assembly.GetName.Name, ".", strForm))

theForm.Show()

My problem is that I want to also be able to open forms that have
constructors that require a parameter eg. Form1(217).
When I try changing the strForm variable to "Form1(217)", i get an
error because it appears to be looking for a form actually called
Form1(217).

Any help is greatly appreciated, cheers.
Paul
 
T

Tom Shelton

Hi,
I am currently able to open forms given a string variable using the
following code:
Dim strForm As String = "Form1"
Dim theForm As Form
theForm = AppDomain.CurrentDomain.CreateInstanceAndUnwrap _
(Me.GetType.Assembly.GetName.Name, System.String.Concat
_
(Me.GetType.Assembly.GetName.Name, ".", strForm))

theForm.Show()

My problem is that I want to also be able to open forms that have
constructors that require a parameter eg. Form1(217).
When I try changing the strForm variable to "Form1(217)", i get an
error because it appears to be looking for a form actually called
Form1(217).

Any help is greatly appreciated, cheers.
Paul

Option Strict On
Option Explicit On

Imports System.Collections.Generic
Imports System.Reflection

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Me.ShowForm("Form2")
End Sub

Private Sub ShowForm(ByVal formType As String)
Dim t As Type = _
Type.GetType(Assembly.GetExecutingAssembly().GetName().Name & "." & formType)
Dim f As Form = _
DirectCast(Activator.CreateInstance(t, New Object() {1}), Form)
f.ShowDialog()
End Sub
End Class
 
C

Cor Ligthert [MVP]

Tom,

I am always curious what people want to achieve with this kind of code.
(Beside to make it unmaintanable). You have to know the name of the form, so
there are plenty of more efficient methods in my idea.

Do you have an idea?

Cor
 
P

Paul Craig

Thanks for your replies Cor and Tom. Tom Im not sure if you read my
whole message, but I need to be able to open a form up with a string
variable and also set its constructors parameters with that same string
eg. "Form1("aParamater"). From what I could see from your example, it
just appears to be a more long winded process to what I already have in
my initial post, but let me know if I missed something.

Cor, not sure if you were actually meaning to ask me rather than Tom
the reasoning behind the need for this code. The reason is because I
have a lot of forms, and I am wanting them all to be handled the same
way with various properties and display locations applied to all these
forms. I am using inheritance but it doesnt cover everything I need,
therefore I am wanting to pass the form name and any of its parameters
as 1 string to this method which then opens the form. I can get my
method I previously posted to open the form if I just pass it the form
name but not if I also pass the parameters.

Paul
 
B

Benson

I have used this kind of code for a long time (in Delphi). It is used in the
Mainmenu. I put, eg. Customer Maintenance - CustMas, to the menu item so
that each time I only need to get the string "CustMas", in this case, then
show the form by the generic procedure.

On the other hand, I used Paul's code with success. But the formname seems
to be case sensitive in VB2005?

Benson.
 
C

Cor Ligthert [MVP]

Paul,

If you have it in a string, you have in fact the name. That is the only
thing you need to open a form.

Therefore why would you look if they are there, what you propose is a time
spending method named late binding. While you can for the same sake set your
information as a table in a shared class (this is another word for a
difficult written module). If you use a module than in my advice write it as
a class however withouth the keyword shared.

MyFormsModule as Module

This you can describe as a class and than use


dim frm as MyFormsModule.Forms("MyWhatEverForm") 'this is a collection in
that MyFormsModule
frm.ShowDialog

Not tested however cannot be far from that.

Cor
 
T

Tom Shelton

Paul said:
Thanks for your replies Cor and Tom. Tom Im not sure if you read my
whole message, but I need to be able to open a form up with a string
variable and also set its constructors parameters with that same string
eg. "Form1("aParamater"). From what I could see from your example, it
just appears to be a more long winded process to what I already have in
my initial post, but let me know if I missed something.

There is no method to directly do what you are asking. All the
creation methods are going to think that your parameters are part of
the name. So, you have a couple of choices:

1) Parse out the parameters from the passed name. I think this is a
bad option.
2) Pass in the parameters as an array of objects.

CreateForm ("Form2", New Object() {1, 2, 3})
CreateForm ("Form3", Nothing)
CreateForm ("Form4", New Object() {"Hi", 2.4}

etc.

You might need to rethink your desing some.
 
T

Tom Shelton

Cor said:
Paul,

If you have it in a string, you have in fact the name. That is the only
thing you need to open a form.

Therefore why would you look if they are there, what you propose is a time
spending method named late binding.

What he is doing is not latebinding. It is dynamic creation. Yes,
there is a penalty for the creation of the object itself, because there
is a lookup of the type in the meta-data. But, once created there is no
more penalty....

' this is late binding
Dim f As object = dyanmiccreate("formname")
f.Show() ' must do runtime lookup of all methods

' this is not
dim f as form = dyanmaiccreate("formname")
form.show() ' no runtime lookup. this is a early bound call.

I use this technique a lot. For things like setup screens, that look
something like the vs options dialog. I have various user controls all
descended from a base type, and i store the type of control associated
with the tree node in the nodes tag propertie. So, then to display the
screen it's a simple matter of grabing the tag property and calling
activator.createinstance. I assign it to a common base type, so there
is no performance penalty for usign the control. Remember in OOP, you
should be programming to the interface and not to the implementation :)
 
T

Tom Shelton

Cor said:
Tom,

I am always curious what people want to achieve with this kind of code.
(Beside to make it unmaintanable).

I must respectfully dissagree with this statement. In fact, I believe
in many situations this kind of code increases the maintainability of
your code - by making it more flexable and resistant to change....

Here is a simple realife example. I have a server application that
takes commands from a client (with parameters) and responds with
results. The number of those commands was begining to grow at a very
rapid pace... add to the fact that i started working with another
developer, and the main server class was starting to come into source
control contention because both were adding commands - it was becomming
somewhat of a pain.

Sure, when I only had a couple of functions something like this was
fine (what follows is vast simplification of the code, and is not the
real implementation - it's also in c# :):

class Server
{
private void ExecuteCommand(string command)
{
switch (command)
{
case "SOMECOMMAND":
this.SOMEMETHOD();
break;
. .....
}
}
}


to solve the above problem, I refactored my code to use a comand
pattern where the server dyanmically created the command object based
on the command name:

so now, i had:
class Server
{
private void ExecuteCommand(string command)
{
ServerCommand command = GetCommandObject (command);
command.Execute();
}
}


abstract class ServerCommand
{
public abstract void Execute();
}

class SomeCommand : ServerCommand
{
public override void Execute()
{
// do cool stuff
}
}

This simplified things in many ways (no particular order):

1) we were no longer touching the server class everytime we added a new
command, so there was no more source control fight.

2) the server class got much simpler - focusing on what it did, handle
client connections and let the command objects handle there single
responsability.

3) extending the server was as simple as inheriting form the
ServerCommand base class and filling in the execute method.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top