Looking for a way around Winforms 10,000 handle limit - winforms

I have been tasked with creating a like for like user interface for a product replacement.
One of the components of the old system was a container that displayed properties in a hierarchy (think treeview like) where each property had a label and value (value could be a textbox, drop down, checkbox, file browse etc)
This is the component that I need to replace and one of the conditions being imposed on me is to front load it with about 5000 items, some of which will be made visible depending on usage context.
My first attempt has been to use a FlowLayoutPanel as the main container populated by TableLayoutPanels indented on left margin that each hold label and edit control.
I hit the problem of the 10,000 control handles limit.
Any suggestions on an alterantive approach to get round this limitation that will allow for the front loading of the 5000 items?
Thanks in advance.

Consider the following guidelines:
1. Do not load all the records at once. Load the data page by page as per request, and render each page of data.
2. Do not show all the records at once. You have a limited window size, even if you load all the data, just show the part that should be visible in the view port. Show the rest of the data when the user scrolls. This way you can dispose the previous elements.
3. Do not use a lot of handles. You can use a control which uses just 1 control handle, like a TreeView or DataGridView or even a custom control for yourself. The key is keeping data in view mode and just show the edit controls when the user focus on a specific item to edit.
Example: DataGridView and ListView controls support virtual mode for loading data. You can also simulate nested data by padding the first cell/item. Also the Treeview control supports events like BeforeExpand which allows you to load child data when the user requests.
For all above examples you can just show the edit controls when the user wants to edit the cell.

Related

WPF render controls in the background

I have an application that has a view area. In the view area contains a grid that will contain a collection of controls, such as images, list views, data grids and text.
One one view will be visible at a time, since there is only one view area. Currently when the action is performed to make a new view active I render the view and set it as a child to the view area. Some views takes up to a couple of second to render, so there is a latency here.
I would like to render all 10 views when the application is first loaded and then just grab the appropriate view when called upon. I have not been able to do this. A lot of my view items are usign proportional sizes, the grid uses the Star for the row and column sizes, so it appears that until the view is bound to a visable area where it can calculate all of its sizing it doesn't actual perform any rendering.
For instance, my data grids still flick as it opens it with all of the columns set to 20 width and then it snaps them to the correct widths after. You can visually notice this on the screen, an intial draw with narrow columns and then they all expand to fill the data grid area.
I want to do all rending in the background, then once it is finished display the final product.
A control cannot perform final rendering until it has a container. Maybe try hosting the views differently. Maybe build your views as pages and host the pages in a frame. I don't guarantee that will be faster but something to look at. Could you use tab? I am pretty sure a tabitem reuses the last rendering or at least pieces of the last rendering. Optimize your individual views. A GridView is typically faster than a DataGrid but may not have the features you need. For a table where I need speed I use a GridView and set the column widths based on the data - 100 rows and 40 columns renders in than 1.0 seconds and I put it in a tabitem and if I come back to the tab (after it has rendered once) it renders in 0.1 seconds. If a view has a lot of data that scrolls then try virtualization. Or load multiple frames in the same column / row and only have one visible at at time.
You could try having a separate view area that is the same size as the main one but that is hidden behind the main one, and put all of your 10 views as children of that one so that they render with the appropriate sizes, then swap them out into the main one as necessary...

what and when should i use editor grid or extjs form

I can make the inseration to the table by extjs editor grid and also through the extjs form , what should i used and when i used what ?
which is better ? i had used the extjs form panel but i haven't used the editor grid ?
should i use the editor grid or not ?
Its about what kind of UX you are providing to your users! Take these scenarios:
1. Frequent modifications
Lets assume a user need to frequently modify, add records to the grid. In this case, using a form panel can be a "long process" for the user. He might have to select the record, click on edit button and the form pops up, edit and finally save.
To reduce the user's click and reduce the process.. you can use the editor grid.
2. Viewing / Filtering / Reports
Common scenario is to use the grid for simply viewing, filtering out required records and use as grid as reports with grouped data, summary data etc. I this case, you may not even have a add functionality. You may have a less chance of edits. In this case you will go for normal grids.
Now, there are situations where the grid display is only a summary. In one of my applications, I have only few fields listed on the grid (only important fields). selecting a row will provide you more details in a window with form panel. In such cases you cannot have editor grid because only part of the data is visible at a given time.
Another viewing scenario is to have a form beside the grid with all the fields and they are bound together. In such a scenario, you have the form panel beside the grid. And when user select a row, the data is loaded into the form. You can provide data modification functionality here. Example!
3. Type of data involved
You also need to consider the data you display and manipulate. Editor grids can be good for quick and frequent changes. But It might not be a good idea for editing long and complex data. For example, would you have a HtmlEditor (Rich text editor) in the editor grid?
You cannot use editor grid when you have data entry in steps (some wizards, step-by-step entry etc). In such cases you will have to go with the FormPanel.
I think these points will help you.

WinForms - How do I create a table using a custom control for each row?

I want to create a table representing data I have, but I want each row to have a custom display. I have developed a little custom control that represents a row and has a few items in it (text box, check box, progress bar), however how do I now in the main form create multiple instances of this for the data I have?
e.g. is there a winforms control I can use to do this? or do I have to take a panel or something and programmatically do it?
I do need to somehow take responses back. So if someone clicks on the button in the 4th row say then I'll need to be able to tell which row it was from.
As an aside would then be a way to BIND the above mentioned visualization of my data to the data itself, say housed in an Array?
thanks
I see two options here:
You can use a DataRepeater. This control can be found in the Microsoft Visual Basic Powerpack. It allows you to place controls on a template which gets copied for each item in the databound collection.
You can create a custom control and manually place one instance of it for each item in a collection, re-creating databinding for the controls in it. This requires you to either expose the controls inside publicly or as properties of the user control.
However, above options are mostly useful for non-tabular data. If your layout is strictly tabular (i. e. rectangular cells in a grid) then you can create a custom DataGridViewCell which takes some time to understand but not too much code. Putting a progress bar into such a cell shouldn't prove too difficult.

Complex .Net 2.0 Windows Forms control: where to start?

In order to make a convenient UI for an .Net 2.0 Winforms application I am working on, I have need for a control that I'm pretty sure goes beyond the "out of the box" behavior of any standard control. A mock-up of what I'm trying to achieve follows:
Mock up http://www.claware.com/images/temp/mockup.png
Essentially, this part of the application attempts to parse words into syllables from tribal languages (no dictionary to refer to; any and all unicode characters are possible.) By the time the user gets this far, he has already defined the vowels / consonants in his language and some other configuration. There is then an iterative process of (1) the application guesses which syllables exist in the language based on some rules, (2) the user refines the guesses, selecting the correct parsings or manually parsing a word, (3) the application "learns" from the user's feedback and makes smarter guesses, (4) repeat until the data is "good enough" to move on.
The control needs to present each word (the grey headers), then all the syllable break guesses (the white areas with dots separating the parts of words.) There is also a way to manually enter a parsing, which will display a text area and save button (at the bottom of the mockup.) When the user hovers over a guess, the background changes and "accept / reject" buttons appear. Clicking on the accept, or entering a manual parsing, removes the entire word from the list. Clicking the reject button removes just that item.
I'm by no means 100% sold on the formatting I have above, but I think you can get a general idea of the types of formatting and functional control I need. The control will also scroll vertically--there may be thousands of words initially.
My question for you experienced WinForms developers is: where to start? I would really, really like to stay within the .Net core framework and extend an existing control as opposed to a third-party control. (At the risk of starting a religious war: yes, I suffer from NIH-syndrome, but it's a conscious decision based on a lot of quick-fix solutions but long-term problems with 3rd party controls.) Where can I get the most "bang for my bucK" and the least reinventing the wheel? ListView? ListBox? ScrollableControl? Do I need to go all the way back to Control and paint everything manually? I appreciate any help that could be provided!
[Edit] Thanks everyone for the ideas. It seems like the most elegant solution for my purposes is to create a custom control consisting of a FlowLayoutPanel and a VScrollBar. The FlowLayoutPanel can contain instances of the custom controls used for each word. But the FlowLayoutPanel is virtual, i.e. it only contains those instances which are visible (and some "just out of scroll"). The VScrollBar events determine what needs to be loaded. A bit of code to write, but isn't too bad and seems to work well.
I would look at the TableLayoutPanel and FlowLayoutPanel controls. These will let you organize a series of controls with moderate ease in a vertical fashion. I would then create a UserControl that consists of a label and 2 buttons. The UserControl will expose properties like Text and events that are exposed for the button clicks.. For each entry in the list, you will create an instance of the UserControl, assign the text value, and handle the click events. The instance will be placed in the Table/Flow panel in the correct order. Both of those layout panels do allow for inserting items between other items so you can add/remove items from the list dynamically.
Edit:
Given the length of what you are trying to render, I would consider using the DataGridView and do some custom rendering to make it perform how you want it to work. Using the rendering events of the DGV you can merge columns, change background colors (like highlighting the dark gray lines), turn on/off the buttons, and handle changing the grid into edit mode for your rows to allow modification or inserting of new values. This method would easily handle large datasets and you could bind directly to them very easily.
Well, this certainly looks like a candidate for a custom component that you should be creating yourself. You can create this using standard .Net drawing commands along with a text-box, and a regular button control.
Now you want to find out where to start.
Create a Windows Forms Control Library project.
Drop in the textbox and the button control.
The panel drawing code should preferably be done by code. This can be done using the regular GDI+ commands.
Edit:
Here's another idea, and one that I've practically used in my own project with great success.
You could use a web-browser control in the app, and show your data as html. You could update the source of the web-browser control based on the input in the textbox, and clicking on the links in the web browser control will give you the event that you can trap to do some action. Your CSS will work.
I used this technique to build the 'desktop' in an app I made called 'Correct Accounting Software'. People loved the desktop so much that it is one of the best loved features of the app.
Here's how I would do it:
Create a custom control. In this custom control, have a ListBox atop a LinkButton, and when the LinkButton is clicked you can make it give way to a TextBox. The ListBoxes will have the top row unselectable... you can probably get the rest from there. When you get your list of words, fill a Scrollable of some kind with one control for each word:
(foreach String word in words){
myScrollable.add(new MyComponent(word));
}
From there, I'm not sure what you want to do with the boxes or the data, but that's my initial idea on the UI setup.
Use the WebBrowser control and generate the HTML markup into it using DocumentStream or DocumentText.

WPF Bind DataTable to repeated user controls

I'm in the process of teaching myself WPF, and I have run into a small issue that I can't find the answer to.
My test app allows image files to be dropped into a StackPanel. Once an image is dropped, a new user control is added to the stack, and displays some meta-data about the file. All is working correctly, and I can iterate through the child controls to retrieve the values.
What I'd prefer to be able to do is allow the user to persist this data to a file, so they can suspend working on the data. The obvious way for me to do this is to store the data in a DataTable and serialise/deserialise it to xml. However, I don't know how to drive the collection of user controls from a DataTable or DataSet object - in fact, I don't even know if this is the right way to go about it in a WPF app. I am more than willing to admit my ignorance here and take better suggestions if there are any.
Summary of the app logic.
1) File is dropped (from Win explorer) onto a StackPanel
2) File triggers creation of a new user control, which is added to the StackPanel
3) Data is populated in the user control
4) Processing data involves iterating through the control collection.
What I'd like
1) File is dropped (from Win explorer) onto a StackPanel
2) File data is inserted into some persistable object (data table?)
3) updated data table drives the generation of the user control to be added to the displayed collection.
4) save / load functionality persists the data for re-use later.
Thanks in advance
You're on the right track with the second approach, what you need to look at is the ItemsControl - that's a thing which can have items added to it. It's the base for ListBox etc, and you can template it to work as you require. Then there's the DataTemplate which handles which controls are displayed and data binding to those controls when an item is added to the underlying data structure. There are quite a few examples around on the net, try Dr WPF.
In order to make everything work the underlying data structure must support change notification. As everything happens automagically, once the Xaml is setup, you can find yourself in an odd situation. You've added data to a data structure, which in turn has caused controls and data to appear in your ItemsControl. How do you link the data items and their visual controls. The answer is to use some built in static methods ItemFromContainer which links from the graphic to your underlying data item, useful to handle click events, and ContainerFromItem which does the reverse.

Resources