AndyD273
AndyD273

Reputation: 7279

Finding out which instance of a form initiated another form or module

I'm trying to figure out the best way to reference a control on a form from within a module. Unfortunately the form is just an instance, so it's not as easy as calling form.control...

    Dim ChildForm As New frmSearch 
    ' Make it a child of this MDI form before showing it. '
    ChildForm.MdiParent = Me
    ChildForm.Show()

That form has an option for printing, which calls another form where certain options are chosen. The print form in turn calls a function in a module, which tries to reference back to the origional form.

childform as new frmSearch -> frmPrintForm -> sub okToPrint (in module Print)

okToPrint tries to reference a listview on frmSearch, but can't find it.

    For Each itmX In frmSearch.lstResults.Items

So the solutions I can think of off the top of my head are:
1. Somehow divine which form is the caller of frmPrintForm
2. Pass ChildForm to the frmPrintForm as a variable to be passed on to module Print..
3. Use frmSearch directly instead of using an instance of it.

Number 1 would be my preference, as I don't want to have to pass forms around like that.

Upvotes: 1

Views: 249

Answers (4)

Heinzi
Heinzi

Reputation: 172478

I'm hesitant to suggest this, because this is "asking for downvotes", but I'll mention it anyway for sake of completeness: If you ensure that there is always only one search form on display, you could globally store a reference to the Search form. (Yes, I said "global variable", now go ahead and downvote. :-P)

Public Class frmSearch
    ...

    Private Shared currentSearchForm As frmSearch

    Public Shared ReadOnly Property Current() As frmSearch
        Get
            Return currentSearchForm
        End Get
    End Property

    Public Sub New()
        ''# Do your constructor stuff here
        ...

        currentSearchForm = Me
    End Sub
End Class

This will allow you to access the last opened search form with frmSearch.Current. Note that this solution has all the drawbacks usually associated with global variables, but I guess it most closely resembles what you are used to in VB6.

The code above is to give you the general idea, there is lots of room for improvement (make the constructor private and use a Shared method instead which ensures that no second instance of the form is opened; set currentSearchForm to Nothing when the form is closed, etc.).

Just to mention this once more, passing the relevant data to the print form is a much cleaner solution, but in the end, the decision is yours, and you should know about all available options.

Upvotes: 2

rascalion
rascalion

Reputation: 1

call frmPrintForm modally: frmPrintForm.Show(ME). Then you can use frmPrintForm.Parent to obtain a reference to the calling instance of frmSearch

Upvotes: 0

Heinzi
Heinzi

Reputation: 172478

Don't pass around forms, pass around data. When the print option is selected, loop through the frmSearch results, put the data into some appropriate data structure (probably some list containing some elements), pass this data to frmPrintForm and, afterwards, to okToPrint.

Yes, this means that more parameters are needed, but it also means that your form frmPrintForm and your sub okToPrint no longer depend on details of frmSearch. This makes it easier to reuse your print functionality and to change stuff in your search form without having to worry about breaking something in a completely unrelated module.

Upvotes: 1

Philip Rieck
Philip Rieck

Reputation: 32578

Can I recommend option #4: Pass just the items that you would get from lstResults.Items? You are no longer passing forms (which I agree is a bad thing), nor even relying on having been called from a form.

Upvotes: 1

Related Questions