WPF 4.5
I've got an app where I show a modal Window from my app's main Window by instantiating it, setting its owner to be the main Window, and then calling ShowDialog(). The modal Window has "Topmost=true". The main Window does not.
When I run my app the modal Window shows in front of the main Window, and it is kept in front of the main Window just as expected. However, I can simply click on the main Window behind the modal Window to Activate the main Window and manipulate it...I can even close it!
In my humble opinion this is definitely not the desired behavior for an application with a modal Window. I'm confused as to why WPF handles it this way. More important, I need a solution that will keep the modal Window in front while also blocking access to the main Window behind it (isn't that supposed to be a basic function of a modal Window?)
I believe this desired behavior has always been the default behavior when using ShowDialog in WinForms (way back in the day.) What am I missing here, and how can I get this working with WPF?
You have to set the owner window before ShowDialog :
modalWindow.Owner = RootWindow;
Related
In Winforms if the MDI child window is maximized it doesn't receive ResizeBegin (or ResizeEnd) events. It does receive Resize events - why the distinction? If the child isn't maximized it does get ResizeBegin/End events. Is there a nice way around this? There are plenty of ugly ways: calling directly from the MDI container ResizeBegin event to the child for example.
The ResizeBegin/End events are generated when the user starts and stops resizing a window. Implemented by a modal loop inside Windows itself, it keeps the window edge following the mouse cursor when the user moves it. ResizeBegin when he clicks a window edge, ResizeEnd when he releases the mouse button.
Clearly no user is involved when you change the Size or ClientSize property of an MDI child window in your code. So no Begin or End, just the Resize event. And just one Resize event trigger, there's no constant train of them like there will be when the user uses the mouse to resize. Which otherwise explains why Begin/End is important, if you do a lot of work in your Resize event handler then you'll bog down the UI pretty heavily. Common with automatic layout, the visible artifacts are not pretty.
If you really have to then you can simply generate the event yourself. Call OnResizeBegin() before, OnResizeEnd() after you change the window's Client/Size property value. That code needs to live inside the window you resize to get the correct event triggered. Pretty unlikely you should be doing this btw. Do beware that MDI automatically resizes an maximized MDI child window, it of course cannot be maximized anymore when you activate another one. You can't wrap that with OnResizeBegin/End() calls.
Hi I have a WPF application with various UserControls that contain key functionality. I want to be able to show say a FileManager UserControl in a tab on the main application, or have a dialog pop up when required, that contains the same UserControl.
It seemed like a good idea to create a modal Window and set its Content to the FileManager Usercontrol. But when I am finished with it, I am not sure how to close the containing Window, using a button on the UserControl. Is there an elegant way of doing this without having to store a reference to the Window in the UserControl?
Thanks for any advice!
Create an Event which is called when the respective button on the user control is clicked. That way, the containing control can react to the event in the appropriate manner. For example, a dialog could just close itself.
Is closing a window something that is integral to the functionality of the control in all the contexts where the control is hosted? E.g Does closing a window apply to the case where the control is hosted in a tab of the main app?
If not then you might be better off separating window closing code out of the UserControl in into the window/dialog that is hosting it - using events or whatever to tie the two together.
When my modal ChildWindow closes, the parent control does not get "un-grayed" and all user input is blocked, forcing me to restart the application. Exact scenario which causes this behavior consistently:
ChildWindow A pops up and user clicks a custom button on the bottom of the window (instead of OK or Cancel). My code does some work and then calls the Close() method for the ChildWindow.
ChildWindow A closes and functionality is restored to parent control (controls are un-grayed).
User causes ChildWindow B to pop up. User clicks system-generated OK or Cancel button.
ChildWindow B closes, but the parent controls are still grayed out and inaccessible.
Either of the windows work fine repeatedly on their own. Any thoughts?
I saw something similar (it might not fix your exact problem) and found some discussion about the ChildWindow here
they suggested this method in the ChildWindow Closed event and it worked for me.
Application.Current.RootVisual.SetValue(Control.IsEnabledProperty, true);
Also try calling this.DialogResult = true instead of the Close method.
I have an application which starts with a simple start screen allowing the user to select either New or Open a project. When selecting New I have a new window displayed which is a wizard that collects data to be passed to the Main window.
I create a new Window for the Main window and show that.
Then I close the wizard easily enough with this.close();
But how do I close the initial window which is the Startup URI window?
Application.Current.MainWindow.Close();
Pass the Startup window to the main window as a constructor parameter or property, then call Close() on it.
I am hosting windowsforms control in WPF popup. Problems below:
If i make StaysOpen=False i can't interact with winform control. StaysOpen to false is required because when clicked outsidet the Popup region, it should close.
if i make StaysOpen=True i can interact with winform control but when i click outside the area of popup, it is not getting closed.
I tried setting StaysOpen=true in MouseEnter of popup and StaysOpen=False in MouseLeave, but MouseLeave fires as and when mouse is over winform control resulting in unexpected behaviour.
I even tried IsMouseCaptureWithin property of popup and found it does not work with winforms (i guess its a bug in framework).
Another problem, i was trying to close popup when root main form (which is windows form) is deactivated (pressed Alt+Tab), but this event (deactivate) is fired even when i enter into one of the controls in windowshostControl in popup.
Desired Behaviour:
should be able to host and interact with winform control in wpf popup.
on clicking on outside the area of popup, popup should close.
Appreciate any inputs.
Thanks.
I've had many problems with the defacto-standard popups in WPF, because they are in fact a new window with their own handle. This means if you drag your application around the screen, the popup stays put (it doesn't move with your window). It also means your popup has some strange behaviors and doesn't interact with your application in ways other controls normally do.
I've created 2 decorator classes to address this problem:
PopupDecorator.cs and
TimeoutPopupDecorator.cs
It's pretty simple to use:
Add a namespace declaration for the new popup classes. i.e.
xmlns:dday_wpf="clr-namespace:DDay.WPF"
Surround the area you want the popup to be able to be displayed with the decorator. i.e.
<dday_wpf:PopupDecorator x:Name="popup">
<dday_wpf:PopupDecorator.Popup>
... contents of popup go here ...
</dday_wpf:PopupDecorator.Popup>
... contents of panel go here ...
</dday_wpf:PopupDecorator>
It works pretty much identically to a normal Popup from that moment on.
This may not solve all your problems, but hopefully it helps.
This sounds a bit like my problem launching a modeless winform control from a WPF form.
Check out my question Why is my WPF textbox "kinda" readonly?.
The just being, based on what Doug said about popups being a window with its own handle, makes this applicable.