We have a MDI main form, which contains a main menu and holds the properties and routines to
- select, read and write a selected DAT-input file, and to convert the data to and from a MS-Access database
- open forms like grids and specificly an InpMatrix (which shows INPUTMATH data).

This InpMatrix is a form with a TableLayoutPanel (TLP) which contains a matrix of usercontrols and holds the
properties and routines to
- read and write data the MS-Access database from and to a (temporary) dataset.
- Draw a matrix with usercontrols, and fill it with data from the dataset
- select, read and write data and properties in the usercontrols

There are 3 usercontrols:
- ucStream which holds the properties and routines of the Stream class
They are presented as the "labels" in the top of the TLP (x-direction)
- ucComponent which holds the properties and routines of the Component class
They are presented as the "labels" on the left of the TLP (y-direction)
- ucCell which holds the properties and routines of the Cell class

Some Routines of the usercontrol are Public, so they are accessible from the InpMatrix form.
In this way a form subroutine can handle multple usercontrols simultaniously.

Some routines of the InpMartix are also Public, so they can be accessed from the main form.
I also need to access the InpMatrix routines from a usercontrol, so clicking on a ucStream will not only
select the cell itself, but will select all the cells in the column.
--> Making the InpMatrix routines Public turns out to be INsufficient to access these routines from a usercontrol.
So to be able to access these routines I tried making them Public shared. No luck: the Public shared functions
are even unaccessible from the main and the InpMatrix itself. I am probably overlooking something obvious...

Have a look at following code-snippet.

public class Test
   public shared Sub Foo()

   End Sub
End Class

Now, to call Foo() method.

Test.Foo()

Thanks for the swift reply, adatapost

This works perfectly if i call the public shared sub ( in the InpMatrix class) from the main, but if I try it from a usercontrol, it fails.
Calling the sub is no problem, but the statements inside react differently somehow.

Maybe it has to do with the functionality of the TLP, but I think I am making an obvious mistake (like the N00b I am). I give you the code snipplets to judge for yourself:

MAIN:

Private Sub mnuINPMAT_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuINPMAT.Click
        Dim INPMAT As New InpMatrix
        INPMAT.MdiParent = Me
        INPMAT.Show()
        'Testen van de public (shared) subs
        INPMAT.SelectCell(2, 2) 'Works fine: selectcell is public, not shared
        'INPMAT.SelectLabels(2, 2)  'Warning:	Access of shared member, constant member, enum member or nested type through an instance; qualifying expression will not be evaluated.
        InpMatrix.SelectLabels(2, 2)  'Error at runtime
    End Sub

InpMatrix:

Public Shared currentRow As New ucComponent
    Public Shared currentColumn As New ucStream
    Public Shared currentCell As New ucCell

    Private Sub INPMATviewer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Testing public (shared) subs
        'Me.SelectCell(3, 3)         'Works fine: selectcell is public, not shared
        'InpMatrix.SelectLabels(3, 3)   'FOUT
    End Sub

    Public Sub SelectCell(ByVal x, ByVal y)                     'De-shared for testing
        Dim mycell As New ucCell
        'mycell = Me.TLP.GetControlFromPosition(x, y)         'Error: Object reference not set to an instance of an object. 
        currentCell = mycell                                  'only when called from usrecontrol inside TLP
        currentCell.ucSelect()
    End Sub
    
    Public Shared Sub SelectLabels(ByVal x, ByVal y)          'Shared to be accessible from usercontrol
        InpMatrix.currentColumn = InpMatrix.TLP.GetControlFromPosition(x, 0)
															  'Error: Object reference not set to an instance of an object. 
        InpMatrix.currentColumn.ucSelect()                    'when called from main, InpMatrix(itself) or usrecontrol 
        InpMatrix.currentRow = InpMatrix.TLP.GetControlFromPosition(0, y)
        InpMatrix.currentRow.ucSelect()
    End Sub

Private Sub TLP_MouseClick( _
    ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles TLP.MouseClick
        Dim Row As Integer = 0
        Dim VSpace As Integer = 0
        For Each h As Integer In TLP.GetRowHeights()
            Dim Column As Integer = 0
            Dim HSpace As Integer = 0
            For Each w As Integer In TLP.GetColumnWidths()
                Dim Rect As New Rectangle(HSpace, VSpace, w, h)
                If (Rect.Contains(e.Location)) Then

                    Me.SelectCell(Column, Row)				'Works fine: selectcell is public, not shared
                    InpMatrix.SelectLabels(2, 2)			'Error at runtime

                    Return
                End If
                HSpace += w
                Column += 1
            Next
            VSpace += h
            Row += 1
        Next
    End Sub

Usercontrol:

Public Sub ucSelect()            
        If Selected Then DoubleSelected = True
        Selected = True
        BackColor = clrSelect
        If Selected Then
             CMS.Items(0).Text = "Unselect Cell"
             cmbCellLabel.Visible = True
        End If
    End Sub
This article has been dead for over six months. Start a new discussion instead.