|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Creating a form object from string namefor school and one of the requirements is that every screen should have a "Help" button. I could do it by writing a clumsy case statement like this: sub showHelp(byval frm as String) Select Case (frm) Case "Form1" dim help as new Form1 help.Show() Case "Form2" Dim help as new Form2 help.Show() .... etc I searched and found Activator. I think this will make for better code. So I wrote: Sub ShowHelp(ByVal strFrom As String) Dim frmhelp = Activator.CreateInstance(Nothing, strFrom) frmhelp.show() End Sub but now I'm getting a TypeLoadException that says: Could not load type 'hlpForm1' from assembly 'TestHelp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. The form I'm testing from is Form1 and I do have a form hlpForm1 defined. They are in the same Namespace and in the same assembly in the same project. I'm lost. Can someone please help and tell me what I'm doing wrong? Thanks. MikeB wrote:
Show quoteHide quote > Hi, I'd appreciate some help, please. I'm writing a VS2005 VB project I use this kind of dynamic code all the time for creating user controls> for school and one of the requirements is that every screen should have > a "Help" button. > > I could do it by writing a clumsy case statement like this: > > sub showHelp(byval frm as String) > Select Case (frm) > Case "Form1" > dim help as new Form1 > help.Show() > Case "Form2" > Dim help as new Form2 > help.Show() > ... etc > > I searched and found Activator. I think this will make for better code. > > So I wrote: > > Sub ShowHelp(ByVal strFrom As String) > Dim frmhelp = Activator.CreateInstance(Nothing, strFrom) > frmhelp.show() > End Sub > > > but now I'm getting a TypeLoadException that says: > > Could not load type 'hlpForm1' from assembly 'TestHelp, > Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. > > The form I'm testing from is Form1 and I do have a form hlpForm1 > defined. They are in the same Namespace and in the same assembly in the > same project. > > I'm lost. Can someone please help and tell me what I'm doing wrong? > Thanks. for screens on wizards or such, I have also used it to implement command objects for a server. It made extending the servers command set much simpler - I simply inherited from an abstract base command object, and then would override a single method. I never even had to touch the server again - I simply passed the command string to a factory class which returned a reference to the abstract class and used activator to create the actual comman implementation object (the object name was the same as the command). And your right, it can make better code (if used properly). Anyway, for your specific problem - I believe that you need to pass the name of the object. I know your saying that you did - I passed "hlpForm1", but the fact is that isn't really the name of your class. Your class is really going to be something (based on the error message) "TestHelp.hlpForm1". Since all of these are in the same assembly, I would try to change your function like this: Sub ShowHelp(ByVal strFrom As String) Dim frmhelp As Form = DirectCast (Activator.CreateInstance(Nothing, "TestHelp." & strFrom), Form) ' we do have option strict on right? frmhelp.show() End Sub Casting to form is fine because it will be your super class. Anyway, try that and if it doesn't work, maybe you could post a little more of your code. -- Tom Shelton Right on the money Tom, and you're absolutely correct, one must supply the
fully qualified class name. I've successfully used this technique and I've a couple of notes that might be helpful. I prefer to use the overloads of the Activator.CreateInstance method that take a Type as the first parameter as those return Object's as opposed to the other overloads which return ObjectHandle's. This means that one has to call the Type.GetType method using the class name string to get it to work, e.g.: Dim _f As Form = DirectCast(Activator.CreateInstance(Type.GetType("TestHelp." & strFrom), Form) _f.Show() If the target class is in the same assembly and shares the same namespace as the calling code then, (although they wern't designed for this purpose), the System.IO.Path.GetFileNameWithoutExtension and System.IO.Path.ChangeExtension methods can be leveraged to construct the string for the target class name, e,g: Dim _t as Type = Type.GetType(Path.ChangeExtension(Path.GetFileNameWithoutExtension(Me.Name), "GenericForm") Dim _f As Form = DirectCast(Activator.CreateInstance(_t), Form) _f.Show() or Dim _t as Type = Type.GetType(Path.ChangeExtension(Path.GetFileNameWithoutExtension(Me.Name), "GenericForm") Dim _f As Form = DirectCast(Activator.CreateInstance(Type.GetType(Path.ChangeExtension(Path.GetFileNameWithoutExtension(Me.Name), "GenericForm")), Form) _f.Show() This is particular useful where the Namespace is multilevel e.g. if Me.Name returns MyApp.MyX.MainForm then Path.GetFileNameWithoutExtension returns everything before the last '.' and Path.ChangeExtension appends a '.' followed by whatever is specified. Show quoteHide quote "Tom Shelton" <tom_shel***@comcast.net> wrote in message news:1163749746.313002.242880@m73g2000cwd.googlegroups.com... > > MikeB wrote: >> Hi, I'd appreciate some help, please. I'm writing a VS2005 VB project >> for school and one of the requirements is that every screen should have >> a "Help" button. >> >> I could do it by writing a clumsy case statement like this: >> >> sub showHelp(byval frm as String) >> Select Case (frm) >> Case "Form1" >> dim help as new Form1 >> help.Show() >> Case "Form2" >> Dim help as new Form2 >> help.Show() >> ... etc >> >> I searched and found Activator. I think this will make for better code. >> >> So I wrote: >> >> Sub ShowHelp(ByVal strFrom As String) >> Dim frmhelp = Activator.CreateInstance(Nothing, strFrom) >> frmhelp.show() >> End Sub >> >> >> but now I'm getting a TypeLoadException that says: >> >> Could not load type 'hlpForm1' from assembly 'TestHelp, >> Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. >> >> The form I'm testing from is Form1 and I do have a form hlpForm1 >> defined. They are in the same Namespace and in the same assembly in the >> same project. >> >> I'm lost. Can someone please help and tell me what I'm doing wrong? >> Thanks. > > I use this kind of dynamic code all the time for creating user controls > for screens on wizards or such, I have also used it to implement > command objects for a server. It made extending the servers command > set much simpler - I simply inherited from an abstract base command > object, and then would override a single method. I never even had to > touch the server again - I simply passed the command string to a > factory class which returned a reference to the abstract class and used > activator to create the actual comman implementation object (the object > name was the same as the command). And your right, it can make better > code (if used properly). > > Anyway, for your specific problem - I believe that you need to pass the > name of the object. I know your saying that you did - I passed > "hlpForm1", but the fact is that isn't really the name of your class. > Your class is really going to be something (based on the error message) > "TestHelp.hlpForm1". Since all of these are in the same assembly, I > would try to change your function like this: > > Sub ShowHelp(ByVal strFrom As String) > Dim frmhelp As Form = DirectCast > (Activator.CreateInstance(Nothing, "TestHelp." & strFrom), Form) ' we > do have option strict on right? > frmhelp.show() > End Sub > > Casting to form is fine because it will be your super class. Anyway, > try that and if it doesn't work, maybe you could post a little more of > your code. > > -- > Tom Shelton > Stephany Young wrote:
> Right on the money Tom, and you're absolutely correct, one must supply the Actually, using the type overload is the way I usally do it. I had> fully qualified class name. > > I've successfully used this technique and I've a couple of notes that might > be helpful. > > I prefer to use the overloads of the Activator.CreateInstance method that > take a Type as the first parameter as those return Object's as opposed to > the other overloads which return ObjectHandle's. This means that one has to > call the Type.GetType method using the class name string to get it to work, > e.g.: forgotten that the other returns an ObjectHandle. -- Tom Shelton Thank you to all for your help. I used this to make it work:
Dim _f As Form = DirectCast(Activator.CreateInstance(Type.GetType("TestHelp." & strFrom), Form) _f.Show() I think there was a ")" missing, but I figured it out. It works great. However, that gave me an idea and I have now created a single form with a picturebox and a rich text box. Into these controls I load two files, each with the same name as the name of the form calling for help. That works too. Since I already have to write all the help text and capture the screen images, it seems simpler to forego the creation of the multiple individual forms my original approach would entail. Comments? Tom Shelton wrote: Show quoteHide quote > Stephany Young wrote: > > Right on the money Tom, and you're absolutely correct, one must supply the > > fully qualified class name. > > > > I've successfully used this technique and I've a couple of notes that might > > be helpful. > > > > I prefer to use the overloads of the Activator.CreateInstance method that > > take a Type as the first parameter as those return Object's as opposed to > > the other overloads which return ObjectHandle's. This means that one has to > > call the Type.GetType method using the class name string to get it to work, > > e.g.: > > Actually, using the type overload is the way I usally do it. I had > forgotten that the other returns an ObjectHandle. > > -- > Tom Shelton Now you're getting into the realm of 'how long is a piece of string?'.
There is no right or wrong answer and everybody will have their own (valid) opinion on the subject. I note in you original post that this is for a school assignment. My advice to you is to address the requirements of the assignment of which you have previously only alluded to one aspect (the help button). If your teacher/tutor is worth his/her salt, part of the marking process will be to gauge how you have gone about the 'problem solving' aspect and, supplying someone else's opinion and/or solution and presenting it as your work is not what it's all about. That said, I will say that, in my opinion, you are on the right track with a 'reusable' concept. Show quoteHide quote "MikeB" <MPBr***@gmail.com> wrote in message news:1163822183.032475.118350@j44g2000cwa.googlegroups.com... > Thank you to all for your help. I used this to make it work: > > Dim _f As Form = > DirectCast(Activator.CreateInstance(Type.GetType("TestHelp." & > strFrom), > Form) > _f.Show() > > I think there was a ")" missing, but I figured it out. It works great. > > However, that gave me an idea and I have now created a single form with > a picturebox and a rich text box. Into these controls I load two files, > each with the same name as the name of the form calling for help. That > works too. Since I already have to write all the help text and capture > the screen images, it seems simpler to forego the creation of the > multiple individual forms my original approach would entail. Comments? > > > Tom Shelton wrote: >> Stephany Young wrote: >> > Right on the money Tom, and you're absolutely correct, one must supply >> > the >> > fully qualified class name. >> > >> > I've successfully used this technique and I've a couple of notes that >> > might >> > be helpful. >> > >> > I prefer to use the overloads of the Activator.CreateInstance method >> > that >> > take a Type as the first parameter as those return Object's as opposed >> > to >> > the other overloads which return ObjectHandle's. This means that one >> > has to >> > call the Type.GetType method using the class name string to get it to >> > work, >> > e.g.: >> >> Actually, using the type overload is the way I usally do it. I had >> forgotten that the other returns an ObjectHandle. >> >> -- >> Tom Shelton > Ouch. I wasn't intending to represent someone else's opinion as my own,
I was merely asking a group of people I think are more experienced than myself if my current plan is better program-wise than my original plan that I presented and that I got help with. If I wanted to use other people's work, a previous copy of this project is doing the rounds, I could have just taken a loook at that to see how it was solved previously. I'm trying to learn here. As for the teacher, I lost more point on pixellated images and bad grammar than on anything else and there is no feedback on the type of code that I write. I figured most of it out from the lecture and working through the book and using the Visual Studio Help. The Activator. thing was just over my head, hence I asked for help. Even if I did ask for help, the solution I have now come up with is not based on any help I've been given, I was just asking if it was good. I prefer it because while I have the working code for the activator., I don't really understand how it does what it does. If my own solution wasn't good, I'd have to spend even more time trying to dig in deep enough to understand how it actually works. With my courseload, time is very scarce. I work part-time and have a full 12 hours of coursework. Stephany Young wrote: Show quoteHide quote > Now you're getting into the realm of 'how long is a piece of string?'. > > There is no right or wrong answer and everybody will have their own (valid) > opinion on the subject. > > I note in you original post that this is for a school assignment. My advice > to you is to address the requirements of the assignment of which you have > previously only alluded to one aspect (the help button). > > If your teacher/tutor is worth his/her salt, part of the marking process > will be to gauge how you have gone about the 'problem solving' aspect and, > supplying someone else's opinion and/or solution and presenting it as your > work is not what it's all about. > > That said, I will say that, in my opinion, you are on the right track with a > 'reusable' concept. > > > "MikeB" <MPBr***@gmail.com> wrote in message > news:1163822183.032475.118350@j44g2000cwa.googlegroups.com... > > Thank you to all for your help. I used this to make it work: > > > > Dim _f As Form = > > DirectCast(Activator.CreateInstance(Type.GetType("TestHelp." & > > strFrom), > > Form) > > _f.Show() > > > > I think there was a ")" missing, but I figured it out. It works great. > > > > However, that gave me an idea and I have now created a single form with > > a picturebox and a rich text box. Into these controls I load two files, > > each with the same name as the name of the form calling for help. That > > works too. Since I already have to write all the help text and capture > > the screen images, it seems simpler to forego the creation of the > > multiple individual forms my original approach would entail. Comments? > > > > > > Tom Shelton wrote: > >> Stephany Young wrote: > >> > Right on the money Tom, and you're absolutely correct, one must supply > >> > the > >> > fully qualified class name. > >> > > >> > I've successfully used this technique and I've a couple of notes that > >> > might > >> > be helpful. > >> > > >> > I prefer to use the overloads of the Activator.CreateInstance method > >> > that > >> > take a Type as the first parameter as those return Object's as opposed > >> > to > >> > the other overloads which return ObjectHandle's. This means that one > >> > has to > >> > call the Type.GetType method using the class name string to get it to > >> > work, > >> > e.g.: > >> > >> Actually, using the type overload is the way I usally do it. I had > >> forgotten that the other returns an ObjectHandle. > >> > >> -- > >> Tom Shelton > > If I understand you correctly and your tutor is putting more emphasis on the
quality of the 'help' content than how it is implemented, then all I can say is that I would be asking for my money back. I appreciate that uasge of the Activator is probably outside or more advanced than the remit of your course. You will note also that my response was to add to Tom's response, rather than addressing your original post. My more recent post was is response to your supplementary question as to whether it was better to use a single form or use a seperate form for each help 'context'. My main point here was that if you polled 20 people on the subject you would, most likely, get 20 different views, all of which are valid. Again, you will note that I did say that, in my view, you were were on the right track with reusability. My other comments were meant to be a generalisation prompted by the number of posts we see in here looking for the answers to homework assignments and were not meant to be a criticism of you personally. Show quoteHide quote "MikeB" <MPBr***@gmail.com> wrote in message news:1163881629.277575.228500@m7g2000cwm.googlegroups.com... > Ouch. I wasn't intending to represent someone else's opinion as my own, > I was merely asking a group of people I think are more experienced than > myself if my current plan is better program-wise than my original plan > that I presented and that I got help with. If I wanted to use other > people's work, a previous copy of this project is doing the rounds, I > could have just taken a loook at that to see how it was solved > previously. I'm trying to learn here. > > As for the teacher, I lost more point on pixellated images and bad > grammar than on anything else and there is no feedback on the type of > code that I write. I figured most of it out from the lecture and > working through the book and using the Visual Studio Help. > > The Activator. thing was just over my head, hence I asked for help. > Even if I did ask for help, the solution I have now come up with is not > based on any help I've been given, I was just asking if it was good. I > prefer it because while I have the working code for the activator., I > don't really understand how it does what it does. If my own solution > wasn't good, I'd have to spend even more time trying to dig in deep > enough to understand how it actually works. With my courseload, time is > very scarce. I work part-time and have a full 12 hours of coursework. > > > Stephany Young wrote: >> Now you're getting into the realm of 'how long is a piece of string?'. >> >> There is no right or wrong answer and everybody will have their own >> (valid) >> opinion on the subject. >> >> I note in you original post that this is for a school assignment. My >> advice >> to you is to address the requirements of the assignment of which you have >> previously only alluded to one aspect (the help button). >> >> If your teacher/tutor is worth his/her salt, part of the marking process >> will be to gauge how you have gone about the 'problem solving' aspect >> and, >> supplying someone else's opinion and/or solution and presenting it as >> your >> work is not what it's all about. >> >> That said, I will say that, in my opinion, you are on the right track >> with a >> 'reusable' concept. >> >> >> "MikeB" <MPBr***@gmail.com> wrote in message >> news:1163822183.032475.118350@j44g2000cwa.googlegroups.com... >> > Thank you to all for your help. I used this to make it work: >> > >> > Dim _f As Form = >> > DirectCast(Activator.CreateInstance(Type.GetType("TestHelp." & >> > strFrom), >> > Form) >> > _f.Show() >> > >> > I think there was a ")" missing, but I figured it out. It works great. >> > >> > However, that gave me an idea and I have now created a single form with >> > a picturebox and a rich text box. Into these controls I load two files, >> > each with the same name as the name of the form calling for help. That >> > works too. Since I already have to write all the help text and capture >> > the screen images, it seems simpler to forego the creation of the >> > multiple individual forms my original approach would entail. Comments? >> > >> > >> > Tom Shelton wrote: >> >> Stephany Young wrote: >> >> > Right on the money Tom, and you're absolutely correct, one must >> >> > supply >> >> > the >> >> > fully qualified class name. >> >> > >> >> > I've successfully used this technique and I've a couple of notes >> >> > that >> >> > might >> >> > be helpful. >> >> > >> >> > I prefer to use the overloads of the Activator.CreateInstance method >> >> > that >> >> > take a Type as the first parameter as those return Object's as >> >> > opposed >> >> > to >> >> > the other overloads which return ObjectHandle's. This means that >> >> > one >> >> > has to >> >> > call the Type.GetType method using the class name string to get it >> >> > to >> >> > work, >> >> > e.g.: >> >> >> >> Actually, using the type overload is the way I usally do it. I had >> >> forgotten that the other returns an ObjectHandle. >> >> >> >> -- >> >> Tom Shelton >> > > Stephany and Tom,
Where is the showed method be better than something as? Private function MyDialogShow(TheText) dim myDialogForm as new MyDialogFormBase MyDialogForm.TheText = TheText return MyDialogFormBase.ShowDialog End function Or if it is about real forms just use the SortedList, with the string in the key and the object in the value. Seriously curious Cor Show quoteHide quote "Stephany Young" <noone@localhost> schreef in bericht news:eov1Vb1CHHA.3916@TK2MSFTNGP06.phx.gbl... > If I understand you correctly and your tutor is putting more emphasis on > the quality of the 'help' content than how it is implemented, then all I > can say is that I would be asking for my money back. > > I appreciate that uasge of the Activator is probably outside or more > advanced than the remit of your course. You will note also that my > response was to add to Tom's response, rather than addressing your > original post. > > My more recent post was is response to your supplementary question as to > whether it was better to use a single form or use a seperate form for each > help 'context'. My main point here was that if you polled 20 people on the > subject you would, most likely, get 20 different views, all of which are > valid. Again, you will note that I did say that, in my view, you were were > on the right track with reusability. > > My other comments were meant to be a generalisation prompted by the number > of posts we see in here looking for the answers to homework assignments > and were not meant to be a criticism of you personally. > > > "MikeB" <MPBr***@gmail.com> wrote in message > news:1163881629.277575.228500@m7g2000cwm.googlegroups.com... >> Ouch. I wasn't intending to represent someone else's opinion as my own, >> I was merely asking a group of people I think are more experienced than >> myself if my current plan is better program-wise than my original plan >> that I presented and that I got help with. If I wanted to use other >> people's work, a previous copy of this project is doing the rounds, I >> could have just taken a loook at that to see how it was solved >> previously. I'm trying to learn here. >> >> As for the teacher, I lost more point on pixellated images and bad >> grammar than on anything else and there is no feedback on the type of >> code that I write. I figured most of it out from the lecture and >> working through the book and using the Visual Studio Help. >> >> The Activator. thing was just over my head, hence I asked for help. >> Even if I did ask for help, the solution I have now come up with is not >> based on any help I've been given, I was just asking if it was good. I >> prefer it because while I have the working code for the activator., I >> don't really understand how it does what it does. If my own solution >> wasn't good, I'd have to spend even more time trying to dig in deep >> enough to understand how it actually works. With my courseload, time is >> very scarce. I work part-time and have a full 12 hours of coursework. >> >> >> Stephany Young wrote: >>> Now you're getting into the realm of 'how long is a piece of string?'. >>> >>> There is no right or wrong answer and everybody will have their own >>> (valid) >>> opinion on the subject. >>> >>> I note in you original post that this is for a school assignment. My >>> advice >>> to you is to address the requirements of the assignment of which you >>> have >>> previously only alluded to one aspect (the help button). >>> >>> If your teacher/tutor is worth his/her salt, part of the marking process >>> will be to gauge how you have gone about the 'problem solving' aspect >>> and, >>> supplying someone else's opinion and/or solution and presenting it as >>> your >>> work is not what it's all about. >>> >>> That said, I will say that, in my opinion, you are on the right track >>> with a >>> 'reusable' concept. >>> >>> >>> "MikeB" <MPBr***@gmail.com> wrote in message >>> news:1163822183.032475.118350@j44g2000cwa.googlegroups.com... >>> > Thank you to all for your help. I used this to make it work: >>> > >>> > Dim _f As Form = >>> > DirectCast(Activator.CreateInstance(Type.GetType("TestHelp." & >>> > strFrom), >>> > Form) >>> > _f.Show() >>> > >>> > I think there was a ")" missing, but I figured it out. It works great. >>> > >>> > However, that gave me an idea and I have now created a single form >>> > with >>> > a picturebox and a rich text box. Into these controls I load two >>> > files, >>> > each with the same name as the name of the form calling for help. That >>> > works too. Since I already have to write all the help text and capture >>> > the screen images, it seems simpler to forego the creation of the >>> > multiple individual forms my original approach would entail. Comments? >>> > >>> > >>> > Tom Shelton wrote: >>> >> Stephany Young wrote: >>> >> > Right on the money Tom, and you're absolutely correct, one must >>> >> > supply >>> >> > the >>> >> > fully qualified class name. >>> >> > >>> >> > I've successfully used this technique and I've a couple of notes >>> >> > that >>> >> > might >>> >> > be helpful. >>> >> > >>> >> > I prefer to use the overloads of the Activator.CreateInstance >>> >> > method >>> >> > that >>> >> > take a Type as the first parameter as those return Object's as >>> >> > opposed >>> >> > to >>> >> > the other overloads which return ObjectHandle's. This means that >>> >> > one >>> >> > has to >>> >> > call the Type.GetType method using the class name string to get it >>> >> > to >>> >> > work, >>> >> > e.g.: >>> >> >>> >> Actually, using the type overload is the way I usally do it. I had >>> >> forgotten that the other returns an ObjectHandle. >>> >> >>> >> -- >>> >> Tom Shelton >>> > >> > > Cor Ligthert [MVP] wrote:
Show quoteHide quote > Stephany and Tom, Cor - I was simply responding to his particular problem with> > Where is the showed method be better than something as? > > Private function MyDialogShow(TheText) > dim myDialogForm as new MyDialogFormBase > MyDialogForm.TheText = TheText > return MyDialogFormBase.ShowDialog > End function > > Or if it is about real forms just use the SortedList, with the string in the > key and the object in the value. > > Seriously curious > > Cor Activator.CreateInstance. To be completely honest, in this particular case that is not the route I would take in a real world app. Essentially, all of these "forms" are the same form just displaying different text. Creating a bunch of forms with the same basic functionality seems a little bit like more work then necessary - and I believe that is what Stephany was hinting at to the OP. And your solution is more along the lines of what would be more correct. Still, I think it is good to become familar with the idea of dyanmic object creation and reflection. -- Tom Shelton
rewriting URL
appsetting in class doesn't work SerlializationException Please help, about primary key and dataset xml file format Speeding up array/file loading Function and Class question Dynamically iterating through log files passing parameter to class from application my class library doesn't contain an assembly - how to add an assem |
|||||||||||||||||||||||