8 Replies - 1044 Views - Last Post: 01 December 2012 - 07:49 PM Rate Topic: -----

#1 Nemico   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 01-December 12

Order of controls in a loop seems to be random.

Posted 01 December 2012 - 02:34 PM

I've made a small Knight's Tour program, and am trying to tighten up the code with a loop instead of doing something one by one, like I had it the first time.

There's a panel containing 25 buttons which represent the board. There is a "solve" button is for displaying a little animation showing the user how to solve the puzzle. The buttons on the board are named Button1 through Button25, all placed in order. This is the code I inserted to test my new method, but it didn't give the results that I expected.

        Private Sub btnSolve_Click(sender As Object, e As EventArgs) Handles btnSolve.Click

        resetboard()

        solve()

    End Sub

Sub solve()

        For Each button In Panel1.Controls
            button.BackColor = Color.Black
            System.Threading.Thread.Sleep(500)
            Refresh()
        Next

    End Sub


It filled in the buttons with a pause in between, like I wanted, but it did it in a seemingly random order (Button18, then 25, then 24, then 10, etc). I had guessed that it would do it in order of name, or tab index, but it doesn't. I can move the buttons around on the form and have it animate the way I wanted, but I'd like to figure this out instead.

How is this order determined?

Is This A Good Question/Topic? 0
  • +

Replies To: Order of controls in a loop seems to be random.

#2 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6536
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 02:48 PM

put a breakpoint on line 12
Then hover your mouse over Controls in line 11.
A tooltip will pop up and you can expand it by clicking the +

That will show you the array of controls.

Are they in a random order there?

Order is really Z order (which are on top of others).
If you have juggled which controls are on top of others then the order in this array changes. Think of it as the order they are painted on the form.

You could make a loop adding all the buttons to a List<Button>.
Then sort that List.
Then use that list for highlighting.
Was This Post Helpful? 1
  • +
  • -

#3 Nemico   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 01-December 12

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 03:04 PM

http://i.imgur.com/2GNSp.png

They're in the order I listed in the OP. Is there a way I can fix that?

I don't know anything about Lists. I've learned a few things about Structures, if that helps.
Was This Post Helpful? 0
  • +
  • -

#4 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6536
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 03:14 PM

In C# it would go like this

List<Button> myButtons = new List<Button>;
foreach (Button b in Panel1.Controls)
{
   myButtons.Add(B)/>;
}
myButtons.Sort();
// Then loop through myButtons from here to do as you like


Someone better versed in VB.NET might be able to translate that snippet for you if you can't manage it.
Was This Post Helpful? 1
  • +
  • -

#5 lar3ry   User is offline

  • Coding Geezer
  • member icon

Reputation: 314
  • View blog
  • Posts: 1,296
  • Joined: 12-September 12

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 03:20 PM

View PostNemico, on 01 December 2012 - 04:04 PM, said:

http://i.imgur.com/2GNSp.png

They're in the order I listed in the OP. Is there a way I can fix that?

I don't know anything about Lists. I've learned a few things about Structures, if that helps.

Lists are jist like arrays, but with more functionality. You can just add stuff to them, and when you're done adding, use a number of different methods to access the elements. If you placed the buttons in the order you want them changed (BackColor), then it becomes quite simple. Give this a try.
        Dim btns As New List(Of Button)
        For Each btn In Panel1.Controls
            btns.Add(btn)
        Next
        btns.Reverse()
        For Each button In btns
            button.BackColor = Color.LightBlue
            Application.DoEvents()
        Next


The Application.DoEvents is there so you can place a breakpoint, and see the action happening as you single-step through the code. This works because the buttons are listed in reverse order to the order in which they were placed, and we just reverse that order in the List.

Be aware, though, if you have placed the buttons out of order, or messed with the ZOrder (I didn't know about that.. thanks, tlhIn`toq!), the result might not be right.

I would have also receommended the List.Sort method, but I don't know how to specify the sorting comparator.
Was This Post Helpful? 2
  • +
  • -

#6 Nemico   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 01-December 12

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 03:52 PM

I removed my original panel, and recreated it by just double clicking on Button a bunch of times. When I executed the List, they changed color in order. From what I can recall, I had just made one row and C&P'd it to make the grid. That must be why they were in such a strange order.

My original method was:

    Public Sub Black(ByVal button As Control)
        button.BackColor = Color.Black
    End Sub

 Private Sub btnSolve_Click(sender As Object, e As EventArgs) Handles btnSolve.Click
        
        sleep()

        Black(Button1)
        sleep()

        Black(Button12)
        sleep()

        Black(Button21)
        sleep()

        Black(Button18)
        sleep()

'and so on...

End Sub

    Sub sleep()
        System.Threading.Thread.Sleep(500)
        Refresh()
    End Sub


It seems that I could have the Solve button add them to the list in the order I want them filled in, then call Sub Solve to execute the list. That seems to be essentially the same thing, though. Am I really getting anything done by doing it that way?

Thanks for teaching me about lists!
Was This Post Helpful? 0
  • +
  • -

#7 _HAWK_   User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1162
  • View blog
  • Posts: 4,444
  • Joined: 02-July 08

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 04:12 PM

It would be better for a timer to handle the changing of the buttons rather than Sleep being called on the UI.
Was This Post Helpful? 1
  • +
  • -

#8 lar3ry   User is offline

  • Coding Geezer
  • member icon

Reputation: 314
  • View blog
  • Posts: 1,296
  • Joined: 12-September 12

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 05:13 PM

View PostNemico, on 01 December 2012 - 04:52 PM, said:

It seems that I could have the Solve button add them to the list in the order I want them filled in, then call Sub Solve to execute the list. That seems to be essentially the same thing, though. Am I really getting anything done by doing it that way?

Thanks for teaching me about lists!

Well, as _HAWK_ pointed out, a Timer is a better solution to waiting between steps. Using the Timer_Tick Sub, you could always just call a subroutine that highlights the next button. Once the buttons are in a List, and in the right order, you can easily mess with their properties without having to know the name of them.

Suppose you have a global variable called index, and you have global variable (List(Of Button)) called btnList. Then, in the Timer_Tick event, you call NextButton()
    Private Sub NextButton()
        btnList(index).BackColor = Color.LightBlue
        If index < btnList.Count - 1 Then
            index += 1
        End If
    End Sub


Was This Post Helpful? 0
  • +
  • -

#9 Nemico   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 4
  • Joined: 01-December 12

Re: Order of controls in a loop seems to be random.

Posted 01 December 2012 - 07:49 PM

Thanks for the suggestion, but I'm going to keep it as Sleep for now.

I did, however, use a List to add a check to acknowledge the user completing the puzzle (whether or not they did it right is irrelevant :P )

    Public Sub Black(ByVal button As Control)
        button.BackColor = Color.Black
        btns.Remove(button)  'without the remove, the user could hit one button 24 times
        btns.Add(button)     'and hit the center button to "win"
    End Sub

    Private Sub Button13_Click(sender As Object, e As EventArgs) Handles Button13.Click
        Black(Button13)    'This is the button they should end on
        Check()
    End Sub

    Public Sub Check()
        If btns.Count = 25 Then
            System.Threading.Thread.Sleep(250)
            For Each Button In Panel1.Controls
                Button.backcolor = Color.Orchid
            Next
        End If
    End Sub


And resetboard() clears the list now.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1