views:

1541

answers:

4

For any custom dialog (form) in a WinForm application I can set its size and position before I display it with:

form.StartPosition = FormStartPosition.Manual;
form.DesktopBounds = MyWindowPosition;

This is particularly important when dealing with multiple monitors. Without such code, when you open a dialog from an application that you have dragged to a second monitor, the dialog appears on the primary monitor. This presents a poor user experience.

I am wondering if there are any hooks to set the position for the standard .NET OpenFileDialog and SaveFileDialog (which do not have a StartPosition property).

A: 

I suspect that the best you can do is make sure you use the overload of ShowDialog that accepts an IWin32Window to use as the parent. This might help it choose an appropriate location; most commonly:

using(var dlg = new OpenFileDialog()) {
    .... setup
    if(dlg.ShowDialog(this) == DialogResult.OK) {
        .... use
    }
}
Marc Gravell
This sounded so simple it had to work (at least it had to be tested)! Alas, both the 0-arg and the 1-arg ShowDialog fail in the same way on this test case:1. Run application. 2. Invoke new OpenFileDialog().ShowDialog(this); dialog appears on same monitor as application. 3. Close dialog. 4. Drag application window to different monitor. 5. Invoke new OpenFileDialog().ShowDialog(this); dialog appears on *original* monitor. Even though I use a fresh OpenFileDialog in step 5, there is still something persistent about the main app's original location.
msorens
I am ( finally :-) choosing Marc's answer as the best because I recently found out it *does* apply to Windows 7. My machine is WinXP where the test case I outline just above still fails. I decided to try the Microsoft forums with the same question and was given a solution that works for WinXP--see this thread (http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/dec48489-0a57-4baa-b401-82266be782e0) for the code.
msorens
+2  A: 

Check out this article on CodeProject. Excerpt:

Here is when the handy .NET NativeWindow comes into the picture, a NativeWindow is a window wrapper where it processes the messages sent by the handle associated to it. It creates a NativeWindow and associates the OpenFileWindow handle to it. From this point, every message sent to OpenFileWindow will be redirected to our own WndProc method in the NativeWindow instead, and we can cancel, modify, or let them pass through.

In our WndProc, we process the message WM_WINDOWPOSCHANGING. If the open dialog is opening, then we will change the original horizontal or vertical size depending of the StartLocation set by the user. It will increment the size of the window to be created. This happens only once when the control is opened.

Also, we will process the message WM_SHOWWINDOW. Here, all controls inside the original OpenFileDialog are created, and we are going to append our control to the open file dialog. This is done by calling a Win32 API SetParent. This API lets you change the parent window. Then, basically what it does is attach our control to the original OpenFileDialog in the location it set, depending on the value of the StartLocation property.

The advantage of it is that we still have complete control over the controls attached to the OpenFileDialog window. This means we can receive events, call methods, and do whatever we want with those controls.

Charlie
A: 

There is quite an old example of one approach on MSDN.

http://msdn.microsoft.com/en-us/library/ms996463.aspx

It includes all the code needed to implement your own OpenFileDialog class that allows extensibility.

andynormancx
A: 

dlg.ShowDialog(new Label()) worked for me.

Rohit