The New keyword means to create a new object of the given type by calling a constructor. But "uc" is a parameter to your Sub. So when you write this line:
Code:
Dim tempobject As New uc()
I'm surprised you aren't being told something like "Unknown type: 'uc'". It implies you probably have some class named "uc" in your program.
So what your sub is doing, as written, is creating a new instance of some class called 'uc', and trying to add it to pnlMain's Controls collection. But whatever 'uc' is, it isn't a Control, so that attempt fails. What I'd expect this method to look like is:
Code:
Public Sub GetUserControl(uc as System.Windows.Forms.Control)
pnlMain.Controls.Clear()
pnlMain.Controls.Add(uc)
End Sub
With respect to your first question, that's a question of application architecture. You
could have your UserControls know that their parent is pnlMain, and that IT's parent is some form, and via casts and Parent properties make the appropriate calls. I don't like that.
In this style of application, since you have a concept of navigation, why not make a Navigation class that knows about pnlMain and is referenced by your UserControls. That way, when they want to update the control in pnlMain, they talk to the Navigation class. Here's about as quick and dirty as that gets:
Code:
Public Class Form1
Private _pnlMain As New Panel()
Private _navigation As Navigation
Public Sub New()
InitializeComponent()
_pnlMain = New Panel()
_pnlMain.Dock = DockStyle.Fill
Controls.Add(_pnlMain)
_navigation = New Navigation(_pnlMain)
Dim startControl = New FirstUserControl(_navigation)
_navigation.SetNewControl(startControl)
End Sub
End Class
Public Class FirstUserControl
Inherits UserControl
Private _navigation As Navigation
Public Sub New(ByVal navigation As Navigation)
_navigation = navigation
BackColor = Color.Crimson
Dock = DockStyle.Fill
Dim btn As New Button() With {.Text = "1"}
AddHandler btn.Click, AddressOf HandleClick
Me.Controls.Add(btn)
End Sub
Private Sub HandleClick(sender As Object, e As EventArgs)
_navigation.SetNewControl(New SecondUserControl(_navigation))
End Sub
End Class
Public Class SecondUserControl
Inherits UserControl
Private _navigation As Navigation
Public Sub New(ByVal navigation As Navigation)
_navigation = navigation
BackColor = Color.Azure
Dock = DockStyle.Fill
Dim btn As New Button() With {.Text = "2"}
AddHandler btn.Click, AddressOf HandleClick
Me.Controls.Add(btn)
End Sub
Private Sub HandleClick(sender As Object, e As EventArgs)
_navigation.SetNewControl(New FirstUserControl(_navigation))
End Sub
End Class
Public Class Navigation
Private _container As Panel
Public Sub New(ByVal container As Panel)
_container = container
End Sub
Public Sub SetNewControl(ByVal uc As UserControl)
_container.Controls.Clear()
_container.Controls.Add(uc)
End Sub
End Class
There's a lot going on, but walk through it. The form creates a Navigation instance after it creates its Panel, and that class is responsible for updating the Panel's children. Each UserControl expects to get that Navigation instance, and will use it to create the next UI when its button is clicked. And it doesn't matter if it's a sub-menu, or even a child control: so long as what you're working with has a reference to that one Navigation object, it can update the UI.
There's a lot of features you could add, but this should be a nudge in the right direction.
(You also probably want to Dispose() of controls instead of
just calling Clear() on the panel, but the timing on that's tricky.)