Very slow design view on a complex form with a lot of controls - vb.net

Let's start with a confession: I came from a VB6 background, and I'm accustomed to coding within the events of objects on a form, and as such my code for events ends up in somewhat random order in the code window. With this habit, it's never been very important to remember the names of controls (although I name them well)... I just double click on a button in the design view, which brings me straight to the code for that control's primary event. If I forget the name of a control, I click it and view properties. It's not a habit I've moved away from.
Well, now this is catching up to me. Using VS Express 2013, I have a form that contains a HUGE number of containers-within-containers, labels, buttons, and other doohickeys. I ported my code from VS.NET Express 2008 where this wasn't a problem. But now the act of selecting any control in the design view takes around 10 seconds before I can view its properties. If I drag to resize a control, and another 10 seconds passes before I can select another control. It makes designing this form nearly impractical.
In this particular project, I'm using use a tab control (which is never visible to the user) to design many "screens" which each contain panels full of controls. The panels for each "screen" are moved out of the tabs and docked into the main form as requested by the user changing screens. (I'm using the term "screen" to mean a window full of controls, usually maximized.)
Within the same project, a simple modal password-change form isn't slow to edit controls visually, even if the complex form is still visible in the IDE.
My question is in three parts:
First, what the heck is it spending all that time doing?
Second, is there a setting I can tweak to improve the speed?
Third, should I give up on trying to speed it up as-is, and move each "screen" into its own form for design purposes to avoid this slowness? (It's a lot of work to do that now... see next paragraph.)
Thus far I have avoided separating "screens" onto separate forms because I don't want a new window to come up when users change screens, and because code for the controls in one screen may affect the properties of controls on other screens... In such cases I prefer not to write out
form.doohickey.text = "blah"
..but rather keep it as ...
doohickey.text = "blah"
I'm using VB but I don't think this question is VB-specific.)

First off, I feel your pain. I have a management section of the application that I'm writing and I'm using a TabControl as well. I have 10 tabs so far and I've only added controls to about 4-5 tabs. I just added up the controls I have and there are about 360 controls so far on this one form and the designer file is ~3300 lines long. Currently anytime I change a property value of one of the controls or go to save the Designer, it takes about 3-4 seconds each time. I have a fairly decent machine; i5-3320M, 8GB RAM, intel 330 SSD, and it still takes a bit for it to do things within the tabControl. It also takes FOREVER to open and load the designer on that form...
What I've found is that it is easier to open a new instance of Visual Studio, create a test application, add a TabControl with the same properties, and design a new tab page from there. When I'm done I do a copy-paste into my actual project. This works great except for the few custom controls I've written in my main application project, I just have to sit and wait while adding them.

I'm now answering my own question. This is the approach I've ended up using, and it helps a lot...
My overall goal was to have an interface that didn't present a lot of windows, but still presented many different "screens".
I used to place all the different controls of different "screens" on separate panels, which were each contained in separate tabs of an invisible TabControl. I would then move those panels to my main form as needed by changing their Parent property of each panel as needed. The only problem with this is that the Winforms designer got ridiculously slow as the number of controls on a form increased into the hundreds.
Now, I am now designing each "screen" as a separate form, each of which contains a panel whose Dock property = Fill. Such a panel contains everything else on the form. The form itself never becomes visible.
As needed for to view various screens, I execute:
ScreenForm.Panel1.Parent = Mainform
...or, depending on how I lay it out...
ScreenForm.Panel1.Parent = Mainform.PanelXYZ
...I also either unload or hide any panels which already exist in the panel's new container.
I was GLADLY SURPRISED to find that the code for the various events of the controls contained in the panels would still run, because such code exists in the first form's file, not the displayed form's file. Luckily, it seems I was wrong. Event code follows the control itself. I can copy/paste not only controls, but also their corresponding event code to new forms for easier development and a faster Winforms designer.
All of this is similar to a MDI interface with maximized windows, but no title bar or [X] is displayed.
Essentially I'm doing everything as I did before, except using separate forms with panels instead of separate tabs with panels. The WinForms designer is much quicker because there aren't so many controls on any form.

I think I accidently found a workaround for saving a lot of time when changing the name of a control on a overpopulated container/project. Before you change the name, toggle False/True the "Generate Member" property of the control you want to rename(I believe you can also locate this under the "Name" property). This adds a few more clicks to the procedure but saves a lot of time. My not-yet-finished project has over 4000 controls and multiple forms and some of them are very "heavy" (10 - 20 seconds to normally change the name of a control). This, of course, don't help in anyway with the loading time of the project (about 35 seconds for me) but I can live with it. Let me know if this works for you too.

Related

Turning off a TabControl/TabPage visual display

We have a number of apps spun from common code, differing primarily in some settings which turn on/off a number of features. Normally each feature is controlled by a number of controls displayed in a TabPage in a TabControl, so depending on the app settings, there might be one or more tabs of controls.
Now in the case where there is only one tab, which is quite common, you end up with a bunch of controls inside a tab which is superfluous. Is there some easy way to turn off the tab control's visuals so it looks like it's controls are on the underlying form instead?

Making multiple forms appear as one in VB.NET

I am writing a Windows Forms application in VB.NET. I have three forms: the main form, which shows a list of accounts, the account form which allows the user to view/edit the information for a specific account, and the policy form which allows the user to view/edit the information on a specific policy for that account. I want the forms to appear as if they are all the same window. Example: when the application starts, the user clicks an account name in the list box on the main form and clicks "edit". What I want to happen is that the window stays in the exact same place and stays the same exact size, only the content of the main form appears to be replaced with the content of the account form. Same thing if the user then chooses to edit a policy from the account form. When the user finishes and clicks "save", the main form comes back up. Through this entire use case, it would appear to the user as if they were viewing the same window the entire time, with the content of that window changing.
How can I do this? I have tried something like:
Dim newForm as New AcctForm
newForm.Location = Me.Location
newForm.Show()
Me.Close()
The problem is that if the user moves the original window, the new window appears where the parent form originally appeared, not where it ended up.
I see this is already in the comments, but what I have done in this case in the past is build each "form" in the application as a custom control. Then I have one actual form, and navigation works by changing which custom control is currently loaded on the parent form. To move from one screen/view to another, you remove the current custom control from the form's controls collection and add the new custom control.
I believe this is superior to manually setting the startup position and size, because you can use the form's .SuspendLayout()/.ResumeLayout() methods to hide the interim state, where there is no control loaded, from the user. This is harder to do when you want one form to be completely replaced by another.
This also makes it easy to set certain form properties in one place and have them be consistent for the application. You can even have an area on the form with controls that will now show in every view.
When using this pattern, I typically have each of my custom controls inherit from a common base. You may not have anything specific you will do with that base at the outset, but it almost always comes in handy later.
Finally, switching to use this scheme is easier than you think. Just go to the code for the each of your current forms, and you will find that each class currently inherits from System.Windows.Forms.Form. Most of the time, all you really need to do is change them to inherit from System.Windows.Forms.Panel and you're most of the way there.
As others have said, it may be better to redesign your application using custom controls or panels etc.
However, to answer your question regarding the seemingly random location of your forms, the first thing to check is that each form has it's StartPosition property set to Manual.
If your main form is resizable, then I would also add code to adjust newForm to the same size too.
I hope that helps with your immediate issues; so that you can move on to redesigning the application!
good morning there is another way . set property for second form to (top most) and use also
from2.show();
that make you switch between forms and keep form2 top other
Thanks
try using ShowDialog()
Dim newForm as New AcctForm
newForm.Location = Me.Location
newForm.ShowDialog()
Me.Close() <-- removed this

VB.NET forms keep disappearing while system is in use

We have a "Core" system that we use to run the business and there are about 15-18 people using it at any one time. The program is written in VB.NET and has about 165 forms.
The way it works is when the user runs the program he/she is prompted to log in and if the login is successful a "Main" form is displayed with a number of menus (Customers, Suppliers...). From there they can click on the menus which open another form on top of the "Main" (the "Main" form needs to be visible in the background because it displays information that is relevant to the users while they are in other screens)
The issue we are having is that if the users have other programs open while using the "Core" system (Outlook, Word, Chrome, anything really) and switch to another program and then back to the system, it only displays the "Main" form and any other forms open on top disappear. The way we get around this is by switching back to the other programs they have open and clicking on the minimise button in the top right corner of the window until all the other programs are minimised, which only leaves the "Core" system visible. However this is becoming a nuisance to all the users (including myself and the other developer) and we really need to sort this issue out in order to keep out staff happy :)
I would appreciate any advice or pointers in the right direction which will help us solve this issue and please feel free to ask if you need any more information.
It seems you are creating the ChildForm from the MainForm but the ChildForm itself is showing itself with Me.ShowDialog(). What you should probably try is showing the form from the MainForm and passing the MainForm in as the parent. This should keep the form tied to it's parent and on top. For example:
childForm.showDialog(Me)
Where Me is the MainForm. This is the documentation for that method.
This is the important part:
Owner Type: System.Windows.Forms.IWin32Window
Any object that implements IWin32Window that represents the top-level window that will own the modal dialog box.
Does that make sense?
Changing code to show dialog will change behavior of your code little bit, like your main from execution will hold till you close child form
But you can you use only show as child (not dialog)
childForm.show (Me)
This will not change anything except whenever you click on main form it will display its entire children on it.

VB.NET - Duplicate existing form in FOR loop

Hey, I'm building a code editor app in VB.NET (Framework 4.0) and it opens all ".por" files into individual forms consisting of a MenuBar and TextBox (multi-line).
Currently I have 20 forms (all duplicates of the first on I designed) and if there are say 4 ".por" files in a directory, the first four will open up while the others hide.
I think it would be far more efficient by coding a new form For each item in form1's ListView...but I want the next so many to be a copy of the first form I designed since I spent a good bit on it.
Thanks in advance!
I decided to use tabs instead.
It wasn't difficult, the problem was I didn't know how to use a form I couldn't see.
By sticking to tabs and making a huge IF statement, simply making a new tab for each new file, and I'm getting used to using controls which haven't actually been created with the designer.
Just passing through a wall here...

WPF User Control is causing Out of Memory Exception

Looking for a free spell checking solution, I thought I was so smart in doing this but I guess not.
I have created a windows form based application and I want the form to add a user specified amount of user controls (with textboxes) on to a panel. The user can then click some button and the controls on this panel are cleared and new ones are added. The user does something and the process is repeated. Now, I wanted these textboxes to support spell checking and looked all over for a free solution.
WPF textboxes support spell checking where the ones in regular win forms do not. I thought I would be able to use these WPF textboxes by adding them to an ElementHost object which is, in turn, within a panel. This panel would be a user control.
So, in my application, I would be able to add instances of these user controls onto the form and make use of .NET's spell checking goodness. This actually worked but after using the application for a while, found that the application would eventually freeze on me due to out of memory errors. I have pinpointed the memory errors to these WPF controls since this problem does not happen with normal textboxes.
When the window is opened and the number of controls is specified, this is pretty much how the controls are added:
Dim xOffset As Integer = 0
For i As Integer = 0 To theNumber
Dim myUserControl As New SpecialUserControl()
myPanel.Controls.Add(myUserControl)
myUserControl.Location = New Point(7, 7)
myUserControl.Location = New Point(xOffset, 7)
xOffset = xOffset + 207
Next
Note that:
myPanel is a panel on a form
SpecialUserControl is the user control with WPF textbox (within an ElementHost object)
When the user pressed a button, the panel is cleared:
myUserControl.Controls.Clear()
The user can then repeat the process.
There are a lot of results on the internet when I tried to find a solution and I'm thinking that the problem I am having is due to the fact that the WPF control is not going away even after clearing the panel. Following this conclusion, I have tried different solutions regarding disposing these controls or setting them to nothing but the memory problem keeps occurring. If someone could give me some advice or ideas here, I'd really appreciate it.
I've decided that this may just be due to the fact that these user controls are being created faster than they can be collected. I've changed the program so that it doesn't create any of these special user controls if it isn't necessary. The program works fine with a more manageable number of WPF controls.