For Each Loop Help

DouglasBell

Active member
Joined
Aug 16, 2011
Messages
38
Programming Experience
Beginner
Hi All

I am using the XmlSerializer to create an array of items

Once created I am using a For Each Loop to go through these items. Buttons are created based on these items.

VB.NET:
    For Each node As MyNode In myNodes
               
                Dim btn As New Button()
                With btn
                    .Size = New Size(464, 108)
                    .BackColor = Color.FromKnownColor(KnownColor.ControlLight)
                    .FlatStyle = FlatStyle.Flat
                    .FlatAppearance.BorderSize = 2
                    .Font = New System.Drawing.Font("Century", 21.75)
                    .TextAlign = ContentAlignment.MiddleLeft
                    .Margin = New Padding(124, 20, 0, 0)
 
                    .Text = node.Text
                    .Tag = node.Nodes
                End With
                AddHandler btn.Click, AddressOf DynamicButton_Click
                buttonsFlowLayoutPanel.Controls.Add(btn)
            Next

This is great as long as there is less than 10 items as I can only have 10 buttons on my screen, so what I am wanting to do is create back and next buttons that will change the buttons based on how many is in the list.

For example each page would be 10 items, so to work out the number of pages I would do. Math.Ceiling(items / 10). So if I had 19 items this would give me 2 pages, Page 1 would display items 1 - 10 Page 2 would display items 11 - 19, you would scroll through the pages using the back and next buttons.

How can I modify my For Each loop to only display the items based ont he current page?

Cheers

DJ[/INDENT]
 
Hi,

Here's an idea for you, assuming that you can modify the structure of your XML file:-

1) Firstly add a numeric sequence in the XML file to each of the nodes to uniquely identify each node as 1, 2, 3, 4, 5 etc.

2) Secondly use LINQ before the running of the For loop to extract the ten buttons that you want to show from the file. The for loop then uses the result of the LINQ query. i.e:-

Dim CurrentButtons = (from node as MyNode In MyNodes Where node.IDNo>=StartNode and node.IDNo<=EndNode Select node Order By node.ID)

3) The Previous button tag property should hold the start number of the previous 10 buttons to show

4) The Next button tag property should hold the start number of the next 10 buttons to show

As you then press the next and previous buttons the LINQ query is re-ran with the next or previous starting and calculated end numbers to retrieve and display the required buttons.

Hope that helps.

Cheers

Ian
 
Hi

Thanks for the reply, the code I am using to create and read the XML was created by another user, I really dont have the knowledge to change the code to do the above.

Cheers

DJ
 
OK,

Another way you could do this then is to add all the nodes to a Dictionary with the key value set to an integer. i.e:-

Dim MyDict as Dictionary(of Integer, MyNode)
Dim Counter as Integer

for each Node as MyNode in MyNodes
Counter+=1
MyDict.Add(Counter,Node)
Next

Each node now has a unique Number from 1 to X associated with each node and using the previous comments that I made you could use the same techniques to create a for loop in the form of :-

for x = StartButtonNo to EndButtonNo
Dim node as MyNode = MyDict(x)
next

You then create your button as normal.

Is that any better?

Cheers

Ian
 
Hi

Thanks for the reply and help it is appreciated.

I tried your code doing the following but I no longer get any values on my buttons. I was hoping the below example would give me the first 6 buttons. I think its probably the way I have implemented the code.

VB.NET:
Dim MyDict as Dictionary(of Integer, MyNode)
Dim Counter as Integer

for each Node as MyNode in MyNodes
  Counter+=1
  MyDict.Add(Counter,Node)
Next

dim i as integer
for x = 0 to 5
 Dim node as MyNode = MyDict(x)
              
                Dim btn As New Button()
                With btn
                    .Size = New Size(464, 108)
                    .BackColor = Color.FromKnownColor(KnownColor.ControlLight)
                    .FlatStyle = FlatStyle.Flat
                    .FlatAppearance.BorderSize = 2
                    .Font = New System.Drawing.Font("Century", 21.75)
                    .TextAlign = ContentAlignment.MiddleLeft
                    .Margin = New Padding(124, 20, 0, 0)
 
                    .Text = node.Text
                    .Tag = node.Nodes
                End With
                AddHandler btn.Click, AddressOf DynamicButton_Click
                buttonsFlowLayoutPanel.Controls.Add(btn)
            Next

Cheers

Dj
 
Hi DJ,

I tried your code doing the following but I no longer get any values on my buttons

My question would be are you even creating any buttons anymore? I would guess not due to the following:-

1) You have defined i as an integer then you have ignored your defined integer and used x to access your Dictionary Entry - this should be For i = 0 to 5.

2) That said, this is not the issue. When you assign the nodes to the Dictionary your are adding the first node with a key of 1. Yet, when you access the Dictionary with For x = 0 to 5 the first key you are trying to access has a value of 0 which does not exist. Since you do not have any error capture statements I would expect that the program is then dropping out.

Try changing the for loop to start at 1 and I think that will then sort the issue.

Cheers,

Ian
 
Hi DJ,

All the above is correct but I made a school boy error. You need to define the Dictionary as Dim MyDict as New Dictionary(of Integer, MyNode).

My apologies, notice the keyword "NEW" this is necessary when creating a new instance of an object that has not yet been initialised.

Cheers,

Ian
 
Hi Ian

Thanks for the help.

The i was a typo in my code its x.

I should have noticed that 0 + 1 = 1 and not 0, school boy error on my part, also probably the biggest issue I am having is I have too much error checking but not letting the program do anything if it finds an error so it ignores it, hence my error checking goes out the window.

I will add the New to the code, I should have seen this as the program was telling me that I was calling an instance of MyDict before it had been assigned.

I am not back at work until monday now so I will change the program then and let you know how it goes.

Cheers

Dj
 
OK DJ,

I hope it solves the problem and let me know on Monday if I can help any further.

With regards to error checking, how are you implementing this? No error check should be ignored and I am surprised that you would state that you have got so much error checking that your program just ignores it???? Does not sound right somehow since every error check should give a response to the exception captured??

Cheers,

Ian
 
Hi Ian

All my buttons work perfectly, and I have implemented my Back and Next buttons, so thanks for the help. The only real change to your code was I had to change MyDict(x) to MyDict.Item(x).

As for my error checking, I was having problems with a particular error and got fed up with the error popup so I commented out the catch on the error checking until I fixed the particular problem and forgot about it, hence I wasnt getting any :)

Cheers

Dj
 
Hi DJ,

Great to hear and no problem with the help. I will have to check the MyDict(x), I was sure this was the correct syntax? Anyway, not to worry and glad this little blip did not cause another problem.

Have a good day and happy programming.

Cheers,

Ian
 
Back
Top