We help IT Professionals succeed at work.
Get Started

Mdi forms, show performance tuning causing a weired issue

TDDatATS
TDDatATS asked
on
1,275 Views
Last Modified: 2013-12-17
Hey guys,

I have a strange problem here. The base of the problem is that showing forms in an MDI form is awfully slow when the forms that need to be shown have a fair amount of controls that need showing. And that's without even taking into account the time for loading data into those controls.

Basically my solution was to set the baseform minimized and set the WindowState back to normal after calling the form.Show() method. This increases the speed significantly which I could visually see and measure after I let loose a StopWatch on the designer generated form with many controls.

Now, overall this approach seems to work, except for the fact that for some reason these same forms seem to be reacting very slow to the first Tab key.

Basically it takes like 2 seconds or something before the code even reaches the KeyDown event when pressing tab. I even tried with ProcessCmdKey, but even that takes a few seconds to reach, which is kind of strange I think.

I've tried all sorts of things, but it does seem like it somehow has something to do with starting the form minimized and setting it back to normal afterwards because when I don't do that, it works fine, but of course, then the showing of the form is slow, so it's bad either way.
Strangely enough, I'm currently having this problem only with designer generated forms, I also use this hierarchy to generate forms dynamically and put them in the same mdi region and they do not suffer this problem. Can there be any difference between forms created at runtime vs forms created at design-time?

My production forms have their own distinct look'n feel, but I tried with a regular form not inheriting any custom baseforms and the problem still persisted.
Different designer generated forms also suffer various slowdown times, many controls in the first tabpage seems to generate little slowdown before the tab command reaches ProcessCmdKey while others take awfully long before tab reaches ProcessCmdKey.
Slow: http://thekillinggoku.centelia.net/images/Slow.png
Fast: http://thekillinggoku.centelia.net/images/Fast.png
Also, I tried by removing the mdiparent assignation, but the problem persisted.

Basically, it's a strange situation, so I'm very curious what can cause something like this since I can't seem to find the problem. I tried recreating the problem in a new forms app, but couldn't seem to get it to have the same problem there.
The forms are called using reflection

So to recap -> designer generated form starts minimized, is set back to normal state and then the first tab takes ages to reach any key event. Without starting minimized, this problem doesn't occur.

Well, it's an expansive explanation, but I hope somebody can shed some light on this strange issue.
// ProcessCmdKey hierarchy from top form to baseform, problem is that the first one is only triggerred after quite a while.
// Start, received ProcessCmdKey (FrmBuyerManagement) with command: Tab
// FrmTabForm.ProcessCmdKey: 00:00:00.0008803
// Start, received ProcessCmdKey (FrmTabForm) with command: Tab
// FrmTabForm.ProcessCmdKey: 00:00:00.0019888
// Start, received ProcessCmdKey (FrmBase) with command: Tab
// FrmTabForm.ProcessCmdKey: 00:00:00.0050462
 
// This is the right execution, except that the first ProcessCmdKey is only executed after 
// about 2 seconds AFTER I press the tab key.
 
// Call stack before the first ProcessCmdKey 
>	AFISH.exe!AFISH.Forms.Relations.FrmBuyerManagement.ProcessCmdKey(ref System.Windows.Forms.Message msg = {msg=0x100 (WM_KEYDOWN) hwnd=0x180c76 wparam=0x9 lparam=0xf0001 result=0x0}, System.Windows.Forms.Keys keyData = LButton | Back) Line 200	C#
 	System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.ProcessCmdKey(ref System.Windows.Forms.Message msg = {msg=0x100 (WM_KEYDOWN) hwnd=0x180c76 wparam=0x9 lparam=0xf0001 result=0x0}, System.Windows.Forms.Keys keyData = LButton | Back) + 0x15 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) + 0x96 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.PreProcessMessage(ref System.Windows.Forms.Message msg) + 0x90 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Control.PreProcessControlMessageInternal(System.Windows.Forms.Control target = {CustomControls.LookupComboBox}, ref System.Windows.Forms.Message msg = {msg=0x100 (WM_KEYDOWN) hwnd=0x180c76 wparam=0x9 lparam=0xf0001 result=0x0}) + 0x101 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(ref System.Windows.Forms.NativeMethods.MSG msg = {System.Windows.Forms.NativeMethods.MSG}) + 0xf6 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(ref System.Windows.Forms.NativeMethods.MSG msg) + 0x5 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x22e bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x177 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes	
 	System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x31 bytes	
 
// Calling the form:
/// <summary>
        /// Uitvoeren van menu item
        /// </summary>
        public void ExecuteEvent()
        {
            if (!string.IsNullOrEmpty(FormName))
            {
                Form baseForm = null;
 
                // Enkel als er is xml data is de formgenerator aanroepen
                if (FormXml != null)
                {
                    // Ja formgenerator gebruiken
                    GenerateForm generator = new GenerateForm();
 
                    // Tonen van form
                    baseForm = generator.Generate(FormName, FormXml, Global.MainForm);
 
                    // Formname gebruiken als title als er geen titel is ingesteld
                    if (string.IsNullOrEmpty(baseForm.Text))
                    {
                        baseForm.Text = Translator.Translate(FormName);
                    }
                }
                else if (!string.IsNullOrEmpty(FormName))
                {
                    // Er is geen formxml data
                    // Via reflection juiste form openen
                    // Assembly.GetExecutingAssembly().GetName().Name + "."
                    baseForm = (Form)Assembly.GetExecutingAssembly().CreateInstance("AFISH.Forms." + FormName);
                }
 
                baseForm.MdiParent = Global.MainForm;
                baseForm.FormClosing += form_FormClosing;
                baseForm.Show();
                baseForm.WindowState = FormWindowState.Normal;
                Global.MainForm.MdiChildren[Global.MainForm.MdiChildren.Count() - 1].LayoutMdi(MdiLayout.Cascade);
                // Force the form to be active
                //baseForm.Focus();
            }
        }
 
        /// <summary>
        /// Form closing event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void form_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Focus the treeview when a form is being closed
            if (!e.Cancel)
            {
                ((Form)sender).Hide();
                ((FrmMain)Global.MainForm).FocusTreeView();
            }
        }
 
        /// <summary>
        /// Form closed event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            // Focus the treeview control when the form is closed
            ((FrmMain)Global.MainForm).FocusTreeView();
        }

Open in new window

Comment
Watch Question
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2008
Commented:
This problem has been solved!
Unlock 1 Answer and 10 Comments.
See Answer
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE