Flashing scrollbar on MDI child window after cursor key hit!

G

Guest

My application has a main form with its "IsMdiContainer" set to 'true'.

I create a form to serve as a child form, setting its "MdiParent" to the
main form before calling its "Show()" method. The "AutoScroll" property is
set to 'false'.

My child form class has two scroll bars which I added manually; an
HScrollBar and a VScrollBar. Each of these scroll bars has its "TabStop"
property set to 'false'. (As mentioned above, the "AutoScroll" property of
the child form class is set to 'false'; I do not want to use the form's
automatic scroll bars.)

Any instance of the child form properly has its OnKeyDown() handler
triggered when the child form has focus and regular keys are pressed.

All works great -- until I press a cursor key (i.e., up, down, left, right).

When I press a cursor key, one of the scroll bars starts to scroll, and
starts to
flash! When I release the cursor key, the scroll bar continues to flash,
and no
other key events are received by the child window.

Wait... I just solved my own problem!

Override OnPreviewKeyDown(), and then disable each scrollbar (set its
"Enabled" property to 'false'), and call Invalidate(false) to put a repaint
message in to the queue for the form. When the scrollbars are disabled, this
is evidently enough to prevent the cursor key from finding a scrollbar and
locking to it, starting the flashing, and capturing the input. Upon repaint
we can set the Enabled property of the scrollbars back to 'true' if
appropriate.

Whew! I thought I was going to have to implement my own "MDI" logic instead
of using the "IsMdiContainer" feature. Wow, the worst part about Windows
Forms is the crazy logic concerning how cursor key events, mouse wheel
events, focus, and other things are handled... What next?!

Anyhow, I am sharing my discovery for the benefit of others.

--- Colin
 
G

Guest

Whoops! Still another problem... Disabling the scrollbars fixed the
problem of the scrollbars stealing control, but now focus is switching to any
other MDI child that happens to be open (when more than one MDI child is
open). So...if I cannot prevent this switching (or quickly recover from this
undesired switch), then maybe I have to give up on "real" MDI... :-(
Totally lame!

--- Colin
 
G

Guest

Okay, after some searching in various forums, I found code that prevents my
application from switching MDI child forms when I hit a cursor key (up, down,
left, right).

I created a base class from which I derive any MDI child form. This base
class has the method that will prevent the bad behavior:

public class FormMDIChildBase : Form
{
protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
if ((keyData == Keys.Right) || (keyData == Keys.Down)
|| (keyData == Keys.Left) || (keyData == Keys.Up))
{
return (true);
}
return base.ProcessCmdKey(ref m, keyData);
}
}

Then I simply derive any MDI child from my new FormMDIChildBase
class instead of from the Form class directly. This allows me to
put additional MDI child "fixes" in to this base class, and all different
types of MDI child classes will benefit.

Wow -- programming with Windows Forms feels like constantly being on the
border being forced to invest a lot of time developing some work-around of
undesired behavior -- but repeatedly getting just lucky enough to be spared.

Good luck, people!

--- Colin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top