visual txt open net example abrir c# winforms openfiledialog multiple-monitors

txt - openfiledialog visual c#



ConfiguraciĆ³n de la posiciĆ³n de inicio para OpenFileDialog/SaveFileDialog (7)

Para cualquier cuadro de diálogo personalizado (formulario) en una aplicación de WinForm puedo configurar su tamaño y posición antes de mostrarlo con

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

Esto es particularmente importante cuando se trata de monitores múltiples. Sin dicho código, cuando abre un cuadro de diálogo desde una aplicación que ha arrastrado a un segundo monitor, el cuadro de diálogo aparece en el monitor principal. Esto presenta una mala experiencia de usuario.

Me pregunto si hay algún enlace para establecer la posición para el estándar .NET OpenFileDialog y SaveFileDialog (que no tienen una propiedad StartPosition).


Así es como lo hice:

El punto donde quiero mostrar el OpenFileDialog:

Thread posThread = new Thread(positionOpenDialog); posThread.Start(); DialogResult dr = ofd.ShowDialog();

El código de reposicionamiento:

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); [DllImport("user32.dll", EntryPoint = "SetWindowPos")] public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags); /// <summary> /// Find the OpenFileDialog window when it appears, and position it so /// that we can see both dialogs at once. There is no easier way to /// do this (&^%$! Microsoft!). /// </summary> private void positionOpenDialog () { int count = 0; IntPtr zero = (IntPtr)0; const int SWP_NOSIZE = 0x0001; IntPtr wind; while ((wind = FindWindowByCaption(zero, "Open")) == (IntPtr)0) if (++count > 100) return; // Find window failed. else Thread.Sleep(5); SetWindowPos(wind, 0, Right, Top, 0, 0, SWP_NOSIZE); }

Comienzo un hilo que busca una ventana con el título "Abrir". (Normalmente se encuentra en 3 iteraciones o 15 milisegundos). Luego establezco su posición con el asa obtenida. (Consulte la documentación de SetWindowPos para los parámetros de posición / tamaño).

Kludgy.


Echa un vistazo a este artículo en CodeProject. Extracto:

Aquí es cuando el práctico .NET NativeWindow aparece en la imagen, un NativeWindow es un contenedor de ventana donde procesa los mensajes enviados por el identificador asociado. Crea un NativeWindow y le asocia el identificador OpenFileWindow. A partir de este punto, cada mensaje enviado a OpenFileWindow será redirigido a nuestro propio método WndProc en NativeWindow en su lugar, y podemos cancelarlo, modificarlo o dejarlo pasar.

En nuestro WndProc, procesamos el mensaje WM_WINDOWPOSCHANGING. Si se abre el cuadro de diálogo abierto, cambiaremos el tamaño original horizontal o vertical dependiendo de la ubicación de inicio establecida por el usuario. Incrementará el tamaño de la ventana a crear. Esto sucede solo una vez cuando se abre el control.

Además, procesaremos el mensaje WM_SHOWWINDOW. Aquí, se crean todos los controles dentro del OpenFileDialog original, y vamos a agregar nuestro control al cuadro de diálogo de abrir archivo. Esto se hace llamando a un SetParent de API Win32. Esta API le permite cambiar la ventana principal. Entonces, básicamente, lo que hace es adjuntar nuestro control al OpenFileDialog original en la ubicación que establece, dependiendo del valor de la propiedad StartLocation.

La ventaja de esto es que todavía tenemos control completo sobre los controles adjuntos a la ventana de OpenFileDialog. Esto significa que podemos recibir eventos, métodos de llamada y hacer lo que queramos con esos controles.



Muy agradecido por la respuesta de BobB en este caso. Hay algunos más "gotchas". Debe pasar el identificador de PositionForm al llamar a OpenFileDialog1.ShowDialog (PositionForm); de lo contrario, la técnica de BobB no es confiable en todos los casos. Además, ahora que W8.1 lanza un nuevo control de apertura de archivos con SkyDrive en él, la ubicación de la carpeta Documentos en el control de apertura de archivos de W8.1 ahora está atornillada. Así que prefiero abrir el archivo para usar el antiguo control W7 configurando ShowHelp = True.

Aquí está el código VB.NET que terminé usando, mi contribución a la comunidad en caso de que ayude.

Private Function Get_FileName() As String '' Gets an Input File Name from the user, works with multi-monitors Dim OpenFileDialog1 As New OpenFileDialog Dim PositionForm As New Form Dim MyInputFile As String '' The FileDialog() opens in the last Form that was created. It''s buggy! To ensure it appears in the '' area of the current Form, we create a new hidden PositionForm and then delete it afterwards. PositionForm.StartPosition = FormStartPosition.Manual PositionForm.Left = Me.Left + CInt(Me.Width / 2) PositionForm.Top = Me.Top + CInt(Me.Height / 2) PositionForm.Width = 0 PositionForm.Height = 0 PositionForm.FormBorderStyle = Forms.FormBorderStyle.None PositionForm.Visible = False PositionForm.Show() '' Added the statement "ShowHelp = True" to workaround a problem on W8.1 machines with SkyDrive installed. '' It causes the "old" W7 control to be used that does not point to SkyDrive in error. OpenFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) OpenFileDialog1.Filter = "Excel files (*.xls*)|*.xls*|CSV Files (*.csv)|*.csv" OpenFileDialog1.FilterIndex = 1 OpenFileDialog1.RestoreDirectory = True OpenFileDialog1.AutoUpgradeEnabled = False OpenFileDialog1.ShowHelp = True OpenFileDialog1.FileName = "" OpenFileDialog1.SupportMultiDottedExtensions = False OpenFileDialog1.Title = "Select an Excel or .csv file containing patent data or list of Publication Numbers for your project." If OpenFileDialog1.ShowDialog(PositionForm) <> System.Windows.Forms.DialogResult.OK Then Console.WriteLine("No file was selected. Please try again!") PositionForm.Close() PositionForm.Dispose() OpenFileDialog1.Dispose() Return "" End If PositionForm.Close() PositionForm.Dispose() MyInputFile = OpenFileDialog1.FileName OpenFileDialog1.Dispose() Return MyInputFile End Function


OpenFileDialog y SaveFileDialog se ubican en la esquina superior izquierda del área del cliente de la ventana que se muestra más recientemente. Así que simplemente cree una nueva ventana invisible colocada donde desee que aparezca el diálogo antes de crear y mostrar ese diálogo.

Window dialogPositioningWindow = new Window(); dialogPositioningWindow.Left = MainWindow.Left + <left position within main window>; dialogPositioningWindow.Top = MainWindow.Top + <top position within main window>; dialogPositioningWindow.Width = 0; dialogPositioningWindow.Height = 0; dialogPositioningWindow.WindowStyle = WindowStyle.None; dialogPositioningWindow.ResizeMode = ResizeMode.NoResize; dialogPositioningWindow.Show();// OpenFileDialog is positioned in the upper-left corner // of the last shown window (dialogPositioningWindow) Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog(); ... if ((bool)dialog.ShowDialog()){ ... } dialogPositioningWindow.Close();


Sospecho que lo mejor que puede hacer es asegurarse de usar la sobrecarga de ShowDialog que acepta una IWin32Window para usar como padre. Esto podría ayudarlo a elegir una ubicación apropiada; más comúnmente:

using(var dlg = new OpenFileDialog()) { .... setup if(dlg.ShowDialog(this) == DialogResult.OK) { .... use } }


Tuve este problema durante la mayor parte de ayer. La respuesta de BobB fue la que más me ayudó (Gracias BobB).

Incluso puede ir tan lejos como para crear un método privado que cree una ventana y la cierre antes de la llamada al método dialog.ShowDialog() y seguirá OpenFileDialog el OpenFileDialog .

private void openFileDialogWindow() { Window openFileDialogWindow = new Window(); openFileDialogWindow.Left = this.Left; openFileDialogWindow.Top = this.Top; openFileDialogWindow.Width = 0; openFileDialogWindow.Height = 0; openFileDialogWindow.WindowStyle = WindowStyle.None; openFileDialogWindow.ResizeMode = ResizeMode.NoResize; openFileDialogWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen; openFileDialogWindow.Show(); openFileDialogWindow.Close(); openFileDialogWindow = null; }

Luego ShowDialog() en cualquier método antes del método ShowDialog() .

public string SelectWebFolder() { string WebFoldersDestPath = null; CommonOpenFileDialog filePickerDialog = new CommonOpenFileDialog(); // OpenFileDialog Parameters.. openFileDialogWindow(); if (filePickerDialog.ShowDialog() == CommonFileDialogResult.Ok) { WebFoldersDestPath = filePickerDialog.FileName + "//"; } filePickerDialog = null; return WebFoldersDestPath; }