|
-
Sep 4th, 2016, 07:04 AM
#1
Thread Starter
Member
Cannot call function within dynamically created form
Hey guys,
Hoping someone can help with this problem, its killing me at the moment.
I've got a form called main which has on it a datagridview listing tickets from a database.
when a row is doubleclicked, i create a new instance of form 'TicketDetails' like so...
Code:
Dim ThisTicket as new TicketDetails
Show.ThisTicket()
Within 'ThisTicket' there is another datagridview showing the history of the ticket as well as options (called as 'ticketupdate.showdialog') for adding updates.
There is a public function called 'PopulateHistory' within 'TicketDetails' which I call on event ThisTicket.shown.
That works great when you first open ThisTicket, but no matter what I try, I cannot seem to call ThisTicket.populatehistory() from one of my update forms.
I have a 'Confirm Update' button on the ticketupdate form and am trying this...
Code:
Private Sub btnConfirmUpdate_Click(sender As Object, e As EventArgs) Handles btnConfirmUpdate.Click
main.writesql(main.escapechars(internalupdateinput.text))
internalupdateinput.Text = ""
ThisTicket.populatehistory()
Me.Close()
End Sub
But all I get is
'ThisTicket' is not declared or may be inaccessable due to its protection level
The idea is that you open a ticket to view its details and when you submit an update via the updateform, the updateform closes and the dgv for history in ThisTicket refreshes.
It worked fine when I was just using 'TicketDetails.show', but I need TicketDetails to be a multi-instance form.
Can anyone help me out with how I would call back to this function from another form?
Massive thanks in advance for any help!
Last edited by john.muckley; Sep 4th, 2016 at 07:13 AM.
Reason: added code that errors
-
Sep 4th, 2016, 07:54 AM
#2
Re: Cannot call function within dynamically created form
This is a scope issue. You are creating the form in one routine and trying to access it from another. Once you create it and leave the routine it was create in, you lose access to the variable because it is not defined anywhere outside of the routine you created it in.
To be able to create a form in one routine and access it from another, you need to declare the form variable outside of the routine. Once you do that you can instance it in a subroutine and access it from another.
kevin
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Sep 4th, 2016, 08:06 AM
#3
Thread Starter
Member
Re: Cannot call function within dynamically created form
 Originally Posted by kebo
To be able to create a form in one routine and access it from another, you need to declare the form variable outside of the routine. Once you do that you can instance it in a subroutine and access it from another.
kevin
Thanks Kevin! Can you point me in the direction of how I go about doing that?
-
Sep 4th, 2016, 08:10 AM
#4
Re: Cannot call function within dynamically created form
Code:
dim thisTicket AS SomeForm'declared outside the sub
Private sub SomeSub
thisTicket=New SomeForm 'instanced in a sub
thisTicket.Show
End sub
Private Sub SomeOtherSub
thisTicket.SomeMethod 'accessed in some other sub
End Sub
Process control doesn't give you good quality, it gives you consistent quality.
Good quality comes from consistently doing the right things.
Vague general questions have vague general answers. A $100 donation is required for me to help you if you PM me asking for help. Instructions for donating to one of our local charities will be provided.
______________________________ Last edited by kebo : Now. Reason: superfluous typo's
-
Sep 4th, 2016, 08:27 AM
#5
Thread Starter
Member
Re: Cannot call function within dynamically created form
Ok, so in main.vb, I've added...
Code:
Public thisticket As Tech_ViewTicket
in my doubleclick event, I call ThisTicket like so...
Code:
thisticket = New Tech_ViewTicket
thisticket.ticket_header.Text = "Support ticket " & supportcaselist.SelectedRows(0).Cells(1).Value.ToString
thisticket.Show()
So far so good. I can double click on a ticket and 'ThisTicket' is displayed eachtime as a multi-instance form.
I still cant see to call the function though.
The sub in my updateform is like so...
Code:
Private Sub btnConfirmUpdate_Click(sender As Object, e As EventArgs) Handles btnConfirmUpdate.Click
main.writesql(main.escapechars(internalupdateinput.text))
internalupdateinput.Text = ""
ThisTicket.populatehistory()
Me.Close()
End Sub
I still had the
'ThisTicket' is not declared. It may be inaccessable due to its protection level.
warning at first.
Then i thought well if I'm declaring 'ThisTicket' in main.vb, then I need to call it there perhaps, so i tried changing it to...
Code:
Private Sub btnConfirmUpdate_Click(sender As Object, e As EventArgs) Handles btnConfirmUpdate.Click
main.writesql(main.escapechars(internalupdateinput.text))
internalupdateinput.Text = ""
main.ThisTicket.populatehistory()
Me.Close()
End Sub
Calling it this way throws no errors at all and the app executes and runs ok, but the 'populatehistory' function doesnt happen still 
Am I doing something daft?
-
Sep 4th, 2016, 09:59 AM
#6
Re: Cannot call function within dynamically created form
I don't think that's what you want. You have declared the form variable outside the methods (though you might make it Private unless you intend to access it from other forms). However, in the doubleclick event you are creating a new instance each time. That can work, since you are showing the form in there as well, but it's a massive waste. If you were closing the form every time, then it wouldn't be too bad...except that you are showing it non-modally, which means that you could easily end up with several different instances of the form shown, but only the last one will be accessible.
Actually, after reading the rest of what you wrote, I'm thinking that Main.vb is a module...or maybe not. What IS Main.vb? If it was a module, then the variable would be accessible the way you declared it and you wouldn't need that main.ThisTicket thing, but if Main.vb is not a module then the most likely thing is a form, and there's a different argument against it being that. So what is it?
What you should have is the line:
Public thisticket As Tech_ViewTicket
in the same form code page as the double click event.
You then may want to be thinking a bit more about how you create the form and how you display it. If you create a new one every time you doubleclick, there are times when that would be right, but it seems unlikely to be right. If that form has a bunch of DGVs that get loaded when the form is created, then you'd be loading them over and over, which seems like a waste. What might be better is to check whether the form has been created:
Code:
If thisTicket Is Nothing
thisTicket = New Tech_ViewTicket
End If
thisTicket.Show
And only create a new one if you need to. That may not be what you are wanting though.
My usual boring signature: Nothing
 
-
Sep 4th, 2016, 10:05 AM
#7
Re: Cannot call function within dynamically created form
 Originally Posted by john.muckley
...Can anyone help me out with how I would call back to this function from another form?
This other Form will need a concrete reference to the instance of TicketDetails on which you wish to execute PopulateHistory. You can pass this reference either as a Property or via a overloaded constructor (Sub New) in TicketDetails.
So in TicketDetails:
Code:
Class OtherForm
Private ticketDetails As TicketDetails
Public Sub New(ticketDetailsInstance As TicketDetails)
Me.ticketDetails = ticketDetailsInstance
End Sub
End Class
or
Code:
Class OtherForm
Public Property TicketDetailsInstance As TicketDetails
End Class
Another option is to pass a reference directly to the function as a delegate instance referring to PopulateHistory and use that delegate like a function.
-
Sep 4th, 2016, 10:31 AM
#8
Thread Starter
Member
Re: Cannot call function within dynamically created form
 Originally Posted by Shaggy Hiker
Actually, after reading the rest of what you wrote, I'm thinking that Main.vb is a module...or maybe not. What IS Main.vb? If it was a module, then the variable would be accessible the way you declared it and you wouldn't need that main.ThisTicket thing, but if Main.vb is not a module then the most likely thing is a form, and there's a different argument against it being that. So what is it?
Sorry, I should have been more clear.
Main.vb is a form... my main form.
 Originally Posted by Shaggy Hiker
You then may want to be thinking a bit more about how you create the form and how you display it. If you create a new one every time you doubleclick, there are times when that would be right, but it seems unlikely to be right. If that form has a bunch of DGVs that get loaded when the form is created, then you'd be loading them over and over, which seems like a waste. .
The app is basically a ticket system I've built.
It's possible to have multiple tickets open at the same time, hence wanting to be able to create the form multiple times.
Last edited by john.muckley; Sep 4th, 2016 at 10:34 AM.
Reason: added detail
-
Sep 4th, 2016, 11:50 AM
#9
Re: Cannot call function within dynamically created form
Ah, ok, so having multiples open at any one time is acceptable. That's fine then.
However, you do run into a different problem. There is only one form in that variable on the main form. If you create a whole series of ticket forms and show them, each new one will replace the old one, and that old one will no longer be accessible via the main form. Only the final one created will be accessible using this design. If you need to have them ALL be accessible, then you need to do something a bit more complicated.
Rather than a single variable, what you need on main is possibly a List(of....well, something). Now that I look back at it, in the original post you created a form of type TicketDetails. Once you moved it to the form level variable, the type is now Tech_ViewTicket. Are those the same thing and you just changed the type name for the form? The list would be a List(of whateverTheTicketFormTypeIs).
When you create a new form, you would add it to the list. You could then access any of the forms because they'd all be in the list.
However, there are two possible improvements to that. The first is that there is no good way to know which form is which in the list. It sure seems like you know that, because you set a specific header for each form. So, one improvement would be to use a Dictionary(of String, YourFormTypeHere) rather than a List. The string would give you a means to identify which form you wanted to work with.
The other improvement is that the forms would all sit in that list (or Dictionary) potentially for as long as the program ran. That seems like a waste. Once a form has gone away, it might make sense to remove it from the list. You can do that by adding a handler for the Closing event of the form right after it is created. The Closing event handler would have to know which form was being closed (another reason to use the Dictionary approach, though that's not the only way to do it), and remove it from the collection.
My usual boring signature: Nothing
 
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|