Results 1 to 9 of 9

Thread: Cannot call function within dynamically created form

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2013
    Posts
    32

    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

  2. #2
    Still learning kebo's Avatar
    Join Date
    Apr 2004
    Location
    Gardnerville,nv
    Posts
    3,712

    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

  3. #3

    Thread Starter
    Member
    Join Date
    Dec 2013
    Posts
    32

    Re: Cannot call function within dynamically created form

    Quote Originally Posted by kebo View Post
    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?

  4. #4
    Still learning kebo's Avatar
    Join Date
    Apr 2004
    Location
    Gardnerville,nv
    Posts
    3,712

    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

  5. #5

    Thread Starter
    Member
    Join Date
    Dec 2013
    Posts
    32

    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?

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,044

    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

  7. #7
    PowerPoster
    Join Date
    Oct 2010
    Posts
    2,141

    Re: Cannot call function within dynamically created form

    Quote Originally Posted by john.muckley View Post
    ...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.

  8. #8

    Thread Starter
    Member
    Join Date
    Dec 2013
    Posts
    32

    Re: Cannot call function within dynamically created form

    Quote Originally Posted by Shaggy Hiker View Post
    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.

    Quote Originally Posted by Shaggy Hiker View Post
    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

  9. #9
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    35,044

    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
  •  



Click Here to Expand Forum to Full Width