Hello everyone, I am making a custom control which inherits the standard windows Panel object. My control has the ability to align all of the controls in the panel to the left by their index in the Controls array. I am trying to add a method which swaps the location of two controls in the collection so that when the controls are aligned again, those two controls switch their locations. The issue is, the Controls array is Readonly and I am unable to override the Control property to allow it to be Read/Write because it is not declared as overridable. Is there any way for me to access the order of the controls in the collection? I would prefer not to create the control from scratch with my own array.

Thanks in advance

Recommended Answers

All 4 Replies

Does this mean that it is not possible in any way to gain direct access to the panel's control collection?

No it doesn't mean this. If you create the controls during design time you can use the tag property or maybe the name of the control. If you create them during runtime you can create control arrays. If you put them into a container you can access them with something like this:

Private Sub ClearAll()
        For Each ctrl As Control In Me.Controls
            If ctrl.[GetType]().Name = "Panel" Then
            End If

            If ctrl.[GetType]().Name = "GroupBox" Then
            End If
            If ctrl.[GetType]().Name = "ComboBox" Then
                Dim tb As ComboBox = TryCast(ctrl, ComboBox)
                tb.SelectedText = ""
            End If

This works for the inner controls. see this discussion
Also there are a few discussions on this website ------------> just
beside this reply plus there are some others open that also show how to acces the controls. Hope this helps.

I successfully got my alignment to work by using the above tag suggestion. For anyone interested my code is below.

Protected Overrides Sub OnControlAdded(e As ControlEventArgs)
        e.Control.Tag = Me.Controls.IndexOf(e.Control)

        Trace.WriteLine("EVENT(OnControlAdded)-Control added to timeline:" + e.Control.Text)
    End Sub
    Public Sub RemoveControl(ByVal c As Control)
        Dim i As Integer = Convert.ToInt32(c.Tag)


        For Each con As Control In Me.Controls
            If Convert.ToInt32(con.Tag) > i Then
                con.Tag = Convert.ToInt32(con.Tag) - 1
            End If

        Trace.WriteLine("EVENT(RemoveControl)-Control removed from timeline:" + c.Text)
    End Sub

Public Sub AlignControlsLeft(Optional ByVal e As Integer = -1)
        If Me.Controls.Count <= 1 Then Exit Sub
        Dim firstControl As Control = FindByTag(Convert.ToString(1))

        firstControl.Location = New Point(0, (Me.Height / 2) - (firstControl.Height / 2))
        If e = -1 Then e = Me.Controls.Count - 1
        For i As Integer = 2 To e
            Dim thisControl As Control = FindByTag(Convert.ToString(i))
            Dim previousControl As Control = FindByTag(Convert.ToString(i - 1))

            thisControl.Top = previousControl.Top
            thisControl.Left = previousControl.Right
            'thisControl.Location = New Point(previousControl.Right, thisControl.Location.Y)
    End Sub

    Public Function FindByTag(ByVal tag As String) As Control
        For i As Integer = 0 To Me.Controls.Count - 1
            If Me.Controls.Item(i).Tag = tag Then Return Me.Controls.Item(i)
        Return Nothing
    End Function

    Public Sub SwapItems(ByVal a As Integer, ByVal b As Integer)
        FindByTag(Convert.ToString(a)).Tag = b
        FindByTag(Convert.ToString(b)).Tag = a

        For Each con As Control In Me.Controls
            Trace.Write(con.Tag.ToString + ",")
    End Sub
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.