Is MDI Form focused? - c#

I've had so much luck developing my application... until now.
My application's main form is a MDI parent, and I didn't think of adding any MDI children in my tests until tonight.
To my surprise, the MDI parent seems to never "get focus" now. The Focus event and the OnFocus method are never called! I mean... it appears focused but none of the in-code focusing events/methods work. Instead a MDI child reports the focus.
How do I fix this?

This is by design. A form acts as a container for other windows, controls. The controls get the focus, the user interacts with, say, a button or text box. Only when the form doesn't have any controls will it get the focus, only because there's nothing else that can get it. The same thing will happen with the MDI child form as soon as you put a control on it. Or with a Panel or UserControl, other container control types.
A form has the Activate and Deactivate events. ActiveForm tells you with one is currently active. Note the distinction between active and focused.

Related

TopMost property not working

I have a form that when I check a box (Duplicate #), a form pops up (CableID_DuplicateView), and I want it to remain ontop until the checkbox is unchecked. However this isn't happening.
I have set the TopMost property to true both dynamically and statically;
this.TopMost = true;
this.TopMost = Checkbox.Checked;
But if I click on anything on the previous form, it gets shoved to the back.
How can I keep it ontop?
Note: I want the other form to still be accessible beneath the top form. And yes, this is an Mdi application, does that make a difference on the TopMost property?
This worked for my similar problem:
try
yourTopForm.TopLevel=true;
yourTopForm.TopMost=true;
yourTopForm.Show(this);
The overloaded Show(this) funcition to show the form is the important part.
It is impossible to make the windows stay on top in MDI system. You can try to activate the windows, so they pop on the top, but this makes only more harm to other actions. I wouldn't recommend trying that. There is just no working way to make some window TopMost in MDI configuration.
Pass your parent form into the Show method of your Top Most form.

How to change mdi statusstrip label from a child form

I've been searching for a solution for couple of days now, but can't find a simple answer.
I've tried a number of examples found on internet (delegates, properties, even breaking OOP making everything public) but none of these seem to work.
Can someone please write a simplest possible code for the following problem:
I have MDI parent form, and a child form. MDI parent form has a status-strip label. Child form has a button. All I want to do is update the MDI label on click of child form button.
Thanks!!!
It is not the best solution. However, it is the easiest one:
1- Change the access modifier of the status-strip label to public.
2- Unbox the parent form to its real type to be able to access the label:
((ActualMdiParentFormType) this.MdiParent).statusStripLabel.Text = "Value";
There is another solution which is to create an event in the child window and register the parent window to that event. In case that the event fires, the parent window will be notified and in the corresponding event handler of the parent window we can update OUR control.
This is a more "MVVM" like approach.
Check these links for more information:
Pass value between forms using events
http://www.c-sharpcorner.com/uploadfile/yougerthen/mvvm-implementation-for-windows-forms/
MVVM: Tutorial from start to finish?
Hope that helps,

Display UserControl as popup window

I have a UserControl where I have some buttons and textboxes. I was wondering how I can display that UserControl when a user clicks a button.
A user control cannot be a 'popup window', that requires a toplevel window. A form. You can put the user control in a form and use the form's Show() method to make it visible.
Fwiw, turning a user control into a toplevel window is technically possible with the SetTopLevel() method. It isn't worth the hassle, it won't behave like a proper one.
You should paste the user control on a windows form and then make it a modal window. Make a object of that form and then call object.open();

How do I get a user control to be closed when I close a specific form?

When I open from the main screen of the application a child form I also display a user control that should be displayed until the child form is closed or the user closes it. If I set the child form to be usercontrol's parent, the user control is not displayed (so the parent of the user control is the desktop). I used SetWindowPos with HWND_TOPMOST and I get the correct behaviour. now when I close the child form I want the usercontrol to close as well. Do you know what I shoud do to get this?
thanks,
When you Show() the child you can also subscribe to it's Closed or Closing event and use that to properly close the UC.
var f = new ChildForm();
// show userctl
f.Closed += MainForm_ChildClosed_Handler;
void MainForm_ChildClosed_Handler(object s, EventArgs e)
{
// close/hide userctl
}
If you keep a reference towards your usercontrol, you should be able to Close (or even Dispose) it from the Closingevent of his parent.
I don't know what you are doing, a UserControl is meant to be a child control, it should be embedded in a Form. It is technically possible to turn a UC into a top level window (like Form), you'd have to set the TopLevel property to True. That however isn't very productive, the window doesn't have the chrome to make it friendly to use. It is missing the title bar, no easy way for the user to move it around, minimize it, close it. And no easy way to solve focus problems, it can disappear behind another window with no easy way for the user to bring it back to the front. Making it top-most is a hack of sorts to get at least the focusing problem solved, but at rather a deer cost.
Just use the UC as it was intended to be used: put it inside a form. That form should probably be the child form you open. It could also be a third form, say a tool window. Use the Show(owner) overload to keep its Z-order in check and cannot do the disappearing act. That also causes it to automatically close when the owner closes.

Interacting with a form without it activating

I'm trying to implement code-completion popup window in my project. The window is derived from Form. It contains two controls: custom list derived from UserControl (it shows completion possibilities with icons) and a VScrollBar.
When the popup appears, it doesn't steal focus from the editor (form's ShowWithoutActivation is overriden to return true) and the editor sends certain keystrokes to the popup so the user can interact with it using keyboard. So far it works like a charm.
The problem is, I want to allow the user to use mouse as well. But, when the user clicks into the popup window, its form activates and steals focus from the editor. I can react to this by giving the focus back to the editor, I have even set up a Timer to do this regularly, but apart from being a poor solution, the title bar of the editor always flickers when this happens (when the popup is clicked).
Is there any way to interact with the popup form (using mouse) that doesn't make the form activate?
The ShowWithoutActivation's documentation reads: "If your non-activated window needs to use UI controls, you should consider using the ToolStrip controls, such as ToolStripDropDown. These controls are windowless, and will not cause a window to activate when they are selected." This seems exactly like the thing I need, but I want to use a custom control and a scroll bar.
The same problem would be with a tooltip that shows these two arrows to switch method overloads (known from VS) - the whole form would use no controls at all (only render the text and the arrows), but when clicked, it should not activate. The problem could be summarized up to "How to create a form that would never activate, but allow the user to interact with certail controls inside?".
Thanks.
Just override the onFocus event...
public partial class myListBox:ListBox
{
protected override void OnGotFocus(EventArgs e)
{
}
}
The issue is that you're using a Form for this rather than building some custom control that doesn't run in its' own UI thread like a Form does.
The flashing and highlighting is handled by windows whenever a Form activates/focuses. The only thing I cay think of is to make your Form borderless and create/draw/handle your own title bar that doesn't flash when focused.
OK, I may have found a solution. The key seems to be WM_MOUSEACTIVATE message, which the popup form must intercept and respond with MA_NOACTIVATE. But there's a catch - the control derived from UserControl still grabs focus when clicked (the scrollbar luckily doesn't anymore). The problem seems to be in the UserControl.OnMouseDown method, which internally puts focus on the control. There are some ways to fix this:
derive the control from Control instead of UserControl
override the OnMouseDown method and not call base.OnMouseDown there
make the control's CanFocus property return false, but this seems not possible, because that means to make the control either not visible or not enabled, which is both undesirable
The last case when the popup form steals focus seems to be when its resizing (using mouse) ends. But it is safe here to call Owner.Activate() as a result to Activated event...

Categories