Why use a owner window in MessageBox.Show?

前端 未结 8 1173
我寻月下人不归
我寻月下人不归 2020-12-14 17:31

MessageBox.Show has forms like MessageBox.Show( ownerWindow, .... ).

What do I gain by assigning a owner window?

8条回答
  •  温柔的废话
    2020-12-14 17:37

    Based on testing and this other answer, .net will automatically choose the currently focused window in the same thread as your MessageBox.Show() call. To get the correct behavior, you must ensure that you display the MessageBox from the same thread as this window and specify the window the MessageBox is logically associated with as its owner. A MessageBox only modal-ly blocks input to other Forms on the thread from which it is launched. This is probably related to how MessageBox makes itself modal (maybe it intercepts messages aimed at the current thread and only allows some messages through to windows other than itself?). The effect of modal-ly blocking input is that the user will be unable to focus these windows or any controls inside of them and attempting to do so produces the "Ding" sound. Also, if the owner is not specified, the MessageBox will automatically select the active window on the current thread. If the currently active window is from a different thread (or different application!), the MessageBox will have no owner. That means it gets its own Task Bar entry: it behaves as its own distinct window. The user can raise other windows in your application (even if the user cannot interact with them). You can get the situation where your program stops responding to user input with the user confused because the user somehow raised your application's main window after the dialog was displayed. If the owner is properly set, however, trying to raise your main window will cause the MessageBox to be raised and blinked.

    To make this all work nicely with child windows, ensure that each child window has its Owner property set. This will happen automatically if you call ShowDialog() (which makes your custom Form modal (and do pass its owner parameter in the same cases where you would pass owner to MessageBox.Show())).

    Now, most winforms coding consists of writing code directly into event handlers inside a Form subclass. When writing winforms event handlers, you can assume many things. First, you should never have a call to this.Invoke() as a top level statement in a GUI event handler because such handlers are always run on the same thread as the Form subclass was created on. Secondly, for many (but not all) of these handlers, you can assume that the Form has focus (and would be thus automatically chosen by MessageBox.Show() as its owner). For example, when writing code inside of a button's Click event handler (possibly called button1_Click), you can safely assume that the form is focused (because calling PerformClick() on another form's Button is bad practice). However, a Timer.Tick may happen even when your form is not focused. So, in the case of Timer.Tick, there is no need to Invoke() (just like any other winforms event handler) but there is a need to specify owner. This latter case is trickier to notice because the developer must have their application unfocused to notice that a dialog displayed in this case behaves slightly differently from when their application is focused. So, specify owner whenever you need to use Invoke() or if it is possible for the event to be triggered when the window is not focused. This guideline applies when calling MessageBox.Show() and Form.ShowDialog().

    Most of what I discuss here is the result of messing around while reading the other answers.

提交回复
热议问题