|
-
Jun 8th, 2012, 02:58 PM
#1
Thread Starter
Addicted Member
Adding lots of buttons
I have a re sizable panel which i am adding over 100 buttons to. to do it i have a timer which detects any change in the height or width. then clears the panel and re draws all 100 buttons on. however i am encountering issues with flashing (where the buttons are gone for a split second before being repainted)
and also speed issues. it seems to be slowing down the users ability to re size the window.
i was thinking by adding the buttons through its own thread it might combat the main (speed) issue.
any suggestions?
sorry if my problem is not clear!
thanks Tim
-
Jun 8th, 2012, 03:01 PM
#2
Frenzied Member
Re: Adding lots of buttons
If you're using the sizeChanged event, why not just get the total y (from 0 to the sum of the heights of the existing buttons (with any spacing included)) and subtract that from the new size of the panel. Do a little arithmetic to see how many more buttons you can fit and just append them to the end of the panel.
Justin
-
Jun 8th, 2012, 03:18 PM
#3
Re: Adding lots of buttons
I did something like this, though I was adding a custom control rather than a button. What I ended up doing was creating an array of controls sized to the largest size I would allow. All of the control creation and hooking up was done during the form load. Then, on the form, I would determine which ones were actually visible (the rest were off the visible part of the screen) and toggle the visible property. Toggling visibility is FAR faster than creating the control.
The code doesn't really lend itself so much to being posted, but if you'd like to see some of it, I can post various pieces.
EDIT: Also, don't use a timer to detect size changes. There are events for that, and that's where the code should be.
My usual boring signature: Nothing
 
-
Jun 8th, 2012, 03:28 PM
#4
Thread Starter
Addicted Member
Re: Adding lots of buttons
Thanks for the help, i tried the my threading idea but im not too familiar with threading and so i got lots cross thread errors.
i would love to see this code piece if you could show me.
also thanks for the tip on detecting sizes!
-
Jun 8th, 2012, 05:19 PM
#5
Re: Adding lots of buttons
Don't bother with threading. Controls HAVE to be on the UI thread, and controls are all you are talking about. You'd end up doing more work and taking longer to use threading.
Some code:
Code:
'I declared a 2D array of controls:
Private mControls(,) As MortalityTB
'This part is all in the Sub New for the form:
'Calculate the maximum number of controls that will fit on the screen both wide and high.
'This determines the number of controls to create.
Dim wid = CInt(Math.Ceiling(Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width / 113))
Dim ht = CInt(Math.Ceiling(Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height / 24)) - 6
'Redim the array.
ReDim mBulkTBControls(wid - 2, ht - 1)
For x = 0 To wid - 2
For y = 0 To ht - 1
Dim lMortTB = New MortalityTB
lMortTB.Left = (113 * (x + 1))
lMortTB.Top = 24 * (y + 1)
'Add a bunch of handlers
AddHandler lMortTB.MarkClicked, AddressOf HandleMarkClick
AddHandler lMortTB.CommentClicked, AddressOf HandleCommentClick
AddHandler lMortTB.KeyFailure, AddressOf HandleKeyFailure
AddHandler lMortTB.DataChanged, AddressOf HandleDataChanged
AddHandler lMortTB.TextAdditionFailed, AddressOf HandleTextAdditionFailure
mBulkTBControls(x, y) = lMortTB
Next
Next
That part sets up the controls. While I am using the size of the primary screen to figure out the number of controls that can be in the array, you may note that I reduce the height by 6. This is because the area on the form that can have controls is less than the whole form (there is room for some buttons along the bottom).
I was making this into a grid, so I had a list of labels for column headers, and another for row labels, but that's a different issue.
'The code in the ReSize event
Code:
If SizeGrid() AndAlso Not mSuppressEvent Then
ShowData()
End If
First I call SizeGrid to show the proper controls, then I call ShowData to load them. The latter may not be relevant. Since I was making a grid that was MUCH larger than the screen, there were horizontal and vertical scroll bars (the vertical bar only showed up, as needed, like a ListBox). The data that was loaded into the textboxes was based on the value of the two scroll bars. It doesn't sound like you are doing anything like that, but that's what ShowData was all about.
SizeGrid did this:
Code:
Dim rowCount As Integer = CInt(Math.Ceiling((Me.pDisplaySurface.Height - 40) / 24))
'(subtract the height of the column headers (24) plus the height of the horizontal scroll bar (16).
Dim colCount As Integer = CInt(Math.Ceiling(Me.pDisplaySurface.Width / 113))
Dim lControls(,) As MortalityTB
'Only do anything if either count would necessitate a change.
If rowCount <> mRows OrElse colCount <> mColumns Then
'Dim lControls(,) As MortalityTB
mSuppressEvent = True 'This is added because the value will change for the vertical scroll, but it shouldn't do anything at this time.
If mOrderedNames.Count > rowCount Then
vertScroll.Visible = True
vertScroll.Maximum = mOrderedNames.Count - (rowCount - 1)
rowOffset = 16
Else
vertScroll.Visible = False
End If
mSuppressEvent = False
'Now set up all the TB controls.
ReDim lControls(colCount - 2, rowCount - 1)
'This step will move over all existing TB, as well as add any new ones.
For y = 0 To rowCount - 1
For x = 0 To colCount - 2
lControls(x, y) = mBulkTBControls(x, y)
lControls(x, y).Left = (113 * (x + 1)) - rowOffset 'Might have changed the left.
If Not Me.pDisplaySurface.Controls.Contains(lControls(x, y)) Then
Me.pDisplaySurface.Controls.Add(lControls(x, y)) 'All controls are on a panel.
End If
Next
Next
'Now to remove all the TB that need to be removed. In case the thing was reduced in size.
'This removes the columns.
If colCount < mColumns Then
For x = mColumns - 2 To colCount - 1 Step -1
'Delete the textbox for all existing rows.
For y = 0 To mRows - 1
Me.pDisplaySurface.Controls.Remove(mControls(x, y))
Next
Next
End If
'This removes the rows.
If rowCount < mRows Then
For y = mRows - 1 To rowCount Step -1
'Delete the textbox for all existing columns.
For x = 0 To mColumns - 2
Me.pDisplaySurface.Controls.Remove(mControls(x, y))
Next
Next
End If
It's a bit hard to tease out the parts that are relevant to the grid. There was a bit more code that dealt with putting the Row and Column headers in place. All controls are located on a panel rather than on the main form, so the positioning of the controls (top, and height) is based on panel coordinates.
One thing I noticed when I looked at this is that I was creating the Bulk array, but then I was moving just the ones I wanted into a local array. This takes advantage of the fact that controls are reference types. I wasn't even toggling visibility, as I had said earlier. In fact, I was only showing the controls from the local array. 0,0 in the bulk array was 0,0 in the local array. The bulk array holds all the controls that could be shown if the form was at the maximum for the screen, and I copy the needed controls to the local array. Since controls are reference types, all that is copied is a single reference, which may be as little as four bytes. That's pretty fast.
Hope it helps some.
My usual boring signature: Nothing
 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|