why does Form.Modal property doesn't have a setter? - c#

I don't understand why this property doesn't have a setter. What would happen if you were able to set this property?

As others have said, it depends on how the form is currently being used, I.e. whether it was Show()ed or ShowDialog()ed. Whilst the form is being shown, it doesn't make sense to allow you to change it's modality1.
When the form isn't being shown, it also doesn't make sense to have this be a settable property since what matters is whether the next use of the form is via Show or ShowDialog.
Whilst it's true that most forms will only ever be shown either modally or non-modally, the option remains open to use a single form in both manners.
1Especially because when a form is being shown modally via ShowDialog, the code calling ShowDialog is blocked until it returns with the result of the dialog. If you were to change a form to be modal after it was already Shown, there's nobody waiting to receive the dialog result when it returns.

The purpose of Form.Modal property, from the documentation:
Gets a value indicating whether this form is displayed modally.
So, it only checks for the modal status of the form. It doesn't make sense for it to have a setter.
In order to open a form modally, you should use the ShowDialog() method, also as explained in the link above. That way when you check for the Modal property, it returns true.
If your question is whether or not you can have a modal form after it's been shown, the answer is no, you can't. To understand why, you need to know how ShowDialog() makes the form modal in the first place. Check this awesome answer by Hans Passant in order to understand how ShowDialog() works at a technical level.

I don't understand why this property doesn't have a setter. What would
happen if you were able to set this property?
It doesn't have a setter because you cant change its Modal style once the Form has been shown. Although subtle, Modal and and Non Modal forms behave differently in regards to owner, and blocking the caller, and other less obvious things. It seemingly just not worth the confusion of adding this i would imagine.
Further more, users must interact with the Modal/Dialog window before they can return to the parent application. This avoids interrupting the workflow on the main window and by design.
So if you want a Modal Form, call ShowDialog() or else call Show()

Related

Focus lost when IPleaseWaitService is called before a modal dialog using Catel

In summary, I do have a modal dialog in Catel, invoked with:
_uiVisualizerService.ShowDialog(viewModel)
Inside that dialog, I do a long process showing a Wait Service:
_pleasewaitservice.Show();
// HARD WORK here
_pleasewaitservice.Hide();
And Then I invoke another modal dialog.
_uiVisualizerService.ShowDialog(configureViewModel)
However, when I click outside of the application while it is doing the hard work (when the pleasewaitservice is shown), the second modal dialog is displayed behind the main application, so I cannot focus the Window because it is behind and it is modal. I have to close the app from the task killer.
After checking it carefully, I realized that origin is the pleaseWaitService. If I don't show it, the second modal dialog is always displayed correctly.
Does anyone have any hint about how to solve it?
I was googling about how to force to set focus in any Window, but I didn't find anything.
Thanks
Regards
Saul Hidalgo.
You might want to try the BringWindowToTop extension method inside the code-behind of the window:
https://github.com/Catel/Catel/blob/46fcc69575e533eb9e02669ebaa2246894dc98d8/src/Catel.MVVM/Catel.MVVM.Shared/Windows/Extensions/WindowExtensions.cs#L237

Dialog box doing more than just hiding itself on close

According to the MSDN document, the close operation on a form shown with ShowDialog() should only cause the form to be hidden. Subsequent calls to ShowDialog() will unhide the form.
This doesn't seem to be case, exactly. I have a form with a tree view on it. The check states are preserved between calls to ShowDialog() but any node expansion the user has done is reset back to its default state. Also, the Load event is being executed every time as well. So it seems to be doing more than just "hiding" the form. Anyone have any idea what's up?
Thanks
I've experienced this issue myself. For some reason, calling Form.Hide or setting visible = false on a modal form will call Form.Close in at least some cases. To work around it I set the opacity to zero. You can also use Form.Show instead.
It is somewhat intuitive if you imagine the behavior of a modal dialogue. It blocks the parent window. So if you hide it then there would be no active window for the user to interact with. FWIW, I think the behavior should have been that the parent becomes active again. That's just not always the case.

How do I make a custom modal popup window in WPF and have it return a value?

I'm taking a whack at WPF and trying to learn as I go. I'd appreciate any advice offered.
I've got a Window that has a Page attached to it (through a Frame on the Window). When you press a button on the Page, I want a custom window to pop up to present several custom options and be displayed in a manner of my choosing (I'm thinking right now I want it to be a grid but that may change as I go on). When selected, the modal window will disappear and return to the calling method (button press from the Page) the value of the selected choice.
I don't want the standard windows dialog box with the options of yes, no, okay, cancel, or anything like that. This is truly just a custom popup that returns a value to the caller when the user makes their selection on the popup.
Create a new Window subclass, which you can layout however you like. Then in your button click event handler, display it modally using myModalWindow.ShowDialog();. You can then have a property on the window class which you can access after it closes in order to access result data, i.e.:
myModalWindow.ShowDialog();
var data = myModalWindow.SomeResultProperty;
If you really want to have something returned from a method, I suppose you could create your own public method on your window class which internally calls ShowDialog() and then returns a value.

Is there a Form event that gets called right before anything is drawn to the screen?

I've tried overriding the OnLoad event, but the form is getting drawn before this method finishes. I am calling the base.OnLoad method. But, the form is partially getting drawn (artifacts are seen) during the event. I notice this because I'm hitting the database and it is taking some time. In the event, I'm getting some data and binding it to the form's controls. Please don't tell me to use a separate thread. For simplicity, I would rather just show a busy cursor while the data is being loaded.
UPDATE:
Ok, I think you guys/gals have convinced me. I'll use a separate thread. I wasn't aware of the BackgroundWorker and it was very easy to implement. Now my form is loading quickly. And then, all of a sudden my combo boxes are populated. But, I'd like prevent the user from clicking on the combos before they're populated. What is the best way/standard way of doing this using Winforms? Is there a way to turn off input events in the form until the background worker is finished?
I would recommend that you cover the form with a Loading label before you start loading.
You should be able to solve the problem by placing your loading in the constructor code before the call to IntializeComponent(). At this point, the controls on the form have not yet been created (because this is what InitializeComponent does).
However, the form is also not yet visible in this phase. If you want to show a blank form, then I think a possible solution (I haven't tried that, but I think it should work) would be to call this.Show() (to display the form) and Application.DoEvents() to let WinForms process events and display the form.
You could try doing your expensive operations in the form's constructor, so that when it's time to show the form, it already has the data it needs to render. Also look into SuspendLayout/ResumeLayout methods.
But none of these solutions will be as graceful as using a different thread to perform expensive operations.
I am not sure if this will help or not, but the Move event is called before Load.
The Shown event is good for this. Your form will be completely displayed, then the Shown event is fired. This will give the user a clean screen without partially drawn fields while you load your data.
In your Shown event handler, turn on the hourglass, do your work and then turn off the hourglass.
The ComboBox has a BeginUpdate() and EndUpdate() that can be called when adding large amounts of data or slow data to the control. SuspendLayout() and 'ResumeLayout()` on the form may also help with your redraw issues.
You can also disable the control, if all you want is to prevent the user from clicking it. If you disable the form itself, all contained controls will also be disabled.
If you're using background threads, you'll have to make sure you call these from the main UI thread before starting the thread, and again from the main UI thread when the background worker is complete.

csharp winform modal window, able to click on main window

language c#, winform
how do i create a modal window or such a thing that when it still showing
i would still be able to click or interact with the main window..
thanks.
put some code please or links..
Make the dialog non-modal (use Show instead of ShowDialog), and make it top-most (TopMost = true)
Just use the overload of Form.Show() that takes a form as a parameter, like this:
Form f = new Form();
f.Show(this);
This will keep the form always on top of the form that calls it, but still let you click and access the calling form.
Some confusion here I think;
Modal is when the window blocks the underlying window, and must be closed to enable the underlying window to regain control. Form.ShowDialog(owner) is used to accomplish this.
Non-Modal is a window that is opened "in parallell" to the underlying window. Both windows can be accessed and respond to mouse and key events. Form.Show(owner) to accomplish this.
Modality by definition means that you are not able to click anywhere else. You can create another form and show it with Show() method.
Show() Method allows you to click anywhere while ShowDialog() won't

Categories