Not understanding control removal from panel - vb.net

I have a panel with about six controls on the panel. I wanted to remove the controls from the panel and finally did so with MyPanel.Clear(). But before that I tried the following code that runs from a button click:
For Each b As Control In MyItem.MyPanel.Controls
MyItem.MyPanel.Controls.Remove(b)
Next
I would click the button and watch it, as well as the MyItem.MyPanel.Controls.Count in debug. As it went through, the count would reduce: to 5 to 4 to 3, then it would exit. If I clicked the button again it would remove two more, then the last one on the third click, so they all fit the bill and were all removed without changing anything. Why did it take three clicks? I'm obviously missing something simple here, I think, but I don't know what it is, and I'd really like to understand it. If I had to remove specific controls, it looks like I would have had a problem.

I ran into this issue myself and its odd it even lets you do it as you're modifying the collection in the loop you are referring to.This should be a better method.
If you like to remove them based on type
For i = Panel1.Controls.Count - 1 To 0 Step -1
If TypeOf Panel1.Controls(i) Is Label Then
Panel1.Controls.Remove(Panel1.Controls(i))
End If
Next

Odd that VB.NET even lets you do this, but essentially what you are doing is editing the collection you are iterating through. To better understand, pretend you are using a regular for loop from 1 to 6, at the first iteration you are removing object 1, leaving you with 5 objects, making the old number 2 object the first. The next iteration you remove the 2nd thing, which used to be the third, and so on. Most languages this is a run-time error.

What is happening is that you are deleting the controls starting from the first position and moving to the last. If the list has 6 records and you start deleting them like you are, programatically you are saying:
remove(0)
remove(1)
...
remove(5)
While you are doing that, the list is getting smaller. Once you delete the first item it drops from 6 positions to 5, then 4, then 3, etc. So midway through your code it tries to remove item at location 3 (4th item), but since you already removed 3 items, the list's size only contains 3 items and that position does not exist.
To properly remove them all, you would have to start at the back of the list and move to the front.
Perhaps something like:
For i As Integer = (MyItem.MyPanel.Controls.Count- 1) To 0 Step -1
MyItem.mypanel.Controls(i).Dispose()
Next

Related

VBA MSHFLEXGRID wrong .ROW information in the CLICK event

I'm using the VBA MSHFLEXGRID, 2 grids in fact in the same Form, one below the other so when I choose a row in the first grid, the second one shows info regarding the first grid row selection.
Well, the problem is that the second grid, after choosing a row in the first grid which brings to no information in the second one (I put the data through the own grid recordset, and if i dont want it to show information, i do an exit in the load procedure, it gets crazy and the .ROW property in the Click event starts returning a fixed number, like for example 4, instead of the actual row being clicked. Always a number that represents a higher row than the last one (one that is even out of the grid). I tried also the .MOUSEROW and this one returns 0 all the time (when the grid becomes crazy).
This never happens with the first grid, only with the second one. There's nothing I can do without real information about the row being clicked. I've seen that with different resolutions the problem gets reset. Seems not to happen with low resolutions like 1360x768, but it does with 1920x1080 and 2560x1440.
SOLVED! I was trying cases and more cases to try to understand why it happens sometimes in random cases and finally found it. The problem appears when you set the recordset directly to the grid (Set Grid.Recordset = xxxx) and this xxx is empty. It is, EOF. So I was doing a .Clearstructure, and then the SET. After this, if i did another SET (another selection of the second grid) with a non empty recordset, then it would go crazy.
So what I did was simple assigning first a recordset object to check if the SQL query is empty or not, and if it's not empty and only then, assign the recordset to the grid. Oh my god, this was bringing me crazy after a long time.

Proper use of DataGridView?

My application shall allow the user to look at a table (aka "map") 14 x 28 with X and Y axis loaded from a microcontroller (MCU). This can be edited and sent back into microcontroller. I have two arrays that contain the GUI map and MCU map, which allows any differences to be flagged.
I have a DataGridView that displays the data. This works with initial data. I simply can't get new data to be updated into the DataGridView. The DataGridView is in a Form within an Mdi Child. Here's how I command the changes:
'CalDataTable is the DataGridView
'Map is an array of Single
CalDataTable.Rows.Clear()
CalDataTable.Columns.Clear()
For j As Integer = 1 To 16 'Loop through data and populate table
For i As Integer = 1 To 24
CalDataTable.Rows(j).Cells(i).Value = Map(i - 1, j - 1)
Next
Next
This event is launched from a click in the menuStrip of the Mdi Parent, and the data does not update. However, when I launch the update through a button event within the MDI Child form, it works like a charm.
Am I using the wrong tool or what else could I be missing?
Calling .Rows.Clear() and .Columns.Clear() does more work than just emptying the data. It actually removes the rows and columns from the grid. There are no longer any cells in the grid at all. You don't want that. This isn't like Excel, where the workspace is still there even when you delete things. You need the column definitions and row records to still exist.
Instead, loop through and reset each cell to an empty value, whether that's 0, an empty string, or something else. Or, since it looks like the following loop will visit every cell anyway, just remove the Clear() lines completely.

listbox sorting issue when in ownerdrawfixed mode

I have a listbox with the sorted property set to true. When the drawmode is set to normal, it sorts as expected, in alphabetical order. But, when I have the drawmode set to ownerdrawfixed so that I can change the color of certain items, then the sorted order is quite different. It is not as if the sorted property is set to false (which would list the items in the order added to the list), but I have not figured out what order it is using. The item class used to change the color only has 2 properties: the text (as string), and the color... with the text being the first property. Each time I run the program, the list is the same, so it's not random. But it definitely is not alphabetical. I have no code to post since I set the sorted property at design time, there's nothing that would change this in the code.
I am including a screen shot with 4 Listboxes, which should show what is happening.
Sorting Issue
I have searched for listbox sorting issues, to which only 2 posts show, neither of which addresses this issue.
I have found a work-around, but I do not believe this should be necessary, and it is extra processing and overhead that I feel there should not need to be.
I have tried feeding the data into a sorted, drawmode normal, non-visible listbox, and then read this 1 item at a time and feed it into a non-sorted, drawmode ownerdrawfixed listbox so that I can change the color of some items. While this does work, it could eventually slow the program down if there are very many items to be read. And, I have figured out what order it is putting them in if I use a sorted ownerdrawfixed box to begin with. it is putting the first 2 items at the bottom of the list, then alternates top-bottom... so the order would be something like this.... 3, 5, 7, 9, 10, 8, 6, 4, 2, 1. I saw this when I first tried reading the sorted normal list and feeding it into the sorted ownerdrawfixed list to see where it was putting things in regards to order entered.

How can i set an Horizontal scroll or multiline text on a Combobox ? ( Vb.net)

I ' ve a combobox with too long multiple Items . There is any method to set a horizontal scroll in combobox or set a multiline properties for each item ?
Hi Mattia,
There are a couple of methods that are usable as well as effective for this problem you are having, here is the concept that I've created that you may implement in your project;
Original text: C:\path1\path2\path3\path4\file.exe
Combo Box text: C:\path1\p...file.txt
To do this you will 1st have to specify how many characters you want to shown in the start of the text (1st 5 or so) then you must specify how much you would like to leave off at the end (last 6 or so).
I realize this causes a problem, "I wont be able to see the full path!", however adding a 2nd form or a msgbox to display the full text which should initiate the 1st 2-4 secs of display time, this should not be a challenge nor a problem and will make you look like a Pro!
I hope this helped you with your problem or motivated you to go over and beyond!

MS Access 2003 - Automatically show last records in list box on a form rather than first

So I have a form that has a listbox that shows like a ledger. My question is how can I make it display the last records (or have the scroll bar default to the bottom instead of the top), instead of the first few as the default.
Now I don't mean reversing the order from bottom to top instead of top to bottom (though that would be a cool thing to learn how to do), just simply having the bottom of the list (in terms of the scroll bar) shown and the default, so that it is always showing the last 10 or so records (based on the size that I made the list box).
So i think this is simple, but then again, I obviously do not know?!?!
Thanks!
In a suitable event, such as the current event:
Me.ListX.Selected(Me.ListX.ListCount - 1) = True
You could add some code to the form load event so that it will do this:
YourListBox.SetFocus
YourListBox.ListIndex = YourListBox.ListCount - 1
YourListBox.Selected(YourListBox.ListCount - 1) = False
It basically selects the last item in the list box so it will scroll down to it, and then unselects it.
I know this is later but maybe this will help someone in the future who comes upon this thread. This is the code I used to go to the last record then unselect the last record.
YourListBox.SetFocus
YourListBox.Selected(YourListBox.ListCount - 1) = True
YourListBox.Selected(YourListBox.ListCount - 1) = False
How did you set the listbox items? Are they from a database? If yes, then you need to update the SQL statement with an "order by columnName".