4

I am relatively new to windows form programming. I am developing a windows form application which requires user to scroll through the form (I have used a FlowLayoutPanel with AutoScroll=True inside the form). The Panel's source contains an user control which is looped through depending on the number of records.

For instance, if 10 records are present in DB, then 10 user controls are created and added into the Panel when the Form loads, and user will be able to scroll through the 10 items.(Please see the sample image which depicts this scenario) Sample Screen Image

Issue:

The problem occurs when there are more number of records (say 1000), since the usercontrol objects are not disposed and the Handle limit is exceeded, the application crashes (with a message: Error creating window handle). I am aware that this is a memory leak or issue with a bad design.

But I am unable to find a reliable solution here, i have thought about the below options (to overcome the issue) but not sure how to proceed on these:

  1. Load only the UserControls visible on the users screen and dispose other userControls on the fly (as user scrolls or when up/down button is pressed)
  2. Would it be possible to render the usercontrols as image in the panel, and on hovering or clicking of any part, the user control can be re-initialized and triggered to load (This way, the actual user control object would not be in memory)

Could you please suggest a suitable solution / the right way of handling the UserControl objects in the context of this requirement

  • Have you considered using some form of paging? For example, your LayoutPanel would always display 10 UserControls (no scrollbar) and then add page numbers for user to navigate through your records, 10 at a time? This is the usual method when you want to avoid loading a lot of data and having to clutter the UI? – LightBulb Feb 13 '16 at 11:20
  • 3
    That UserControl does not scale very well has to be learned at the School of Hard Knocks. The operating system puts a hard limit on the number of controls you can create, that UserControl plus all of its child controls, it cannot be more than 10,000. Use the kind of control that can display multiple rows of info, like ListView and DataGridView. And look at Google for the proper way to present tens of thousands of results. – Hans Passant Feb 13 '16 at 11:21
  • @LightBulb: Yes, i did consider Paging, it will solve the issue, but this is not very satisfactory with the users (since they do not want to navigate using paging but rather would like to scroll) and so i am trying to figure out if anything else could be done –  Feb 13 '16 at 13:10
  • What was your reason to not use a DataGridView, which was built for such numbers of records ?? – TaW Feb 13 '16 at 14:11
  • @TaW: The design was initially based out of user control, is there a way in which i can manipulate all these user controls into a datagridview (instead of a Panel) to avoid this issue? –  Feb 13 '16 at 14:29
  • @user5922056 Question is closed but this could be the solution: Go for the `Visual Basic Power Toys DataRepeater` control https://msdn.microsoft.com/en-us/library/cc425010(v=vs.80).aspx - You have to install the PowerToys on your dev machine but you can include the `Microsoft.VisualBasic.PowerPacks.Vs.dll` in your bin directory without having to install the setup on your clients. And of course you can use it with C#, too. – Jürgen Steinblock Jun 13 '16 at 08:05

1 Answers1

2

I suggest going for a DataGridView.

I will be able to hold 1000s of records.

You have a choice of either

  • sticking to its straight grid-like layout or
  • chose a hybrid layout

By that I mean a solutuion that shows all but the current record as one row in the grid; the current one can be enlarged and overlaid by one instance of your UserControl that gets loaded from the underlying row's data whenever the selected row changes.

See this post for an example of this technique; there I show how to replace the current row with a larger area, much in the way an accordion control would work..

The rows in the DGV are in fact just a Bitmap and therefore cheap to scroll; the normal way to use a DGV is to rely on its ability the overlay one cell with an edit control of the right type.

The 'accordion trick' extends this to an arbitrary UserControl overlaying a whole row.

Note that the other rows will take a lot less space, which I see as a bonus..

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
  • Thanks for the response. you had mentioned that the rows in the DGV is a bitmap. so is there a way to manipulate 'all' the user controls as separate rows inside the DGV (instead of displaying the grid and overlaying only one row at a time?). –  Feb 13 '16 at 16:13
  • There is no point adding all those UCs, that is exactly what you tried with the FLP. The bitmap I mention is not there for each row; it is created as one single (internal) bitmap that is shown just like an image. Thousands of controls will simply ot work well in Winforms. WPF can handle this with ease, though.. You could go ahead though and draw a bitmap with any layout you like and code a panel or picturebox to display it and to map all mouse- and keyboardactions to react and cause a fresh updated version. But it'll be quite some work, depending on the degree of interactivity. Not recommended – TaW Feb 13 '16 at 16:17