2010-02-04 30 views
8

He estado buscando por toda la web y desafortunadamente nunca encontré con un problema bastante como la mía, así que aquí va:C#, WPF - OpenFileDialog no aparece

Mi C# aplicación de WPF no me mostrará ningún OpenFileDialogs o SafeFileDialogs.

private void btnBrowseNet_Click(object sender, RoutedEventArgs e) 
    { 
     OpenFileDialog ofd = new OpenFileDialog(); 
     ofd.CheckPathExists = true; 
     ofd.Multiselect = false; 
     ofd.Title = "Open Network Configuration Batch file..."; 
     ofd.ValidateNames = true; 
     ofd.Filter = "Comma Seperated Value Files|*.csv"; 

     if (ofd.ShowDialog() == true) 
     { 
      //... 
     } 
    } 

Este código exacto hace en una ocasión exactamente lo que se supone que debe hacer y apenas cinco minutos después, puedo hacer clic en el botón todo lo que quiero, no pasa nada, pero el puntero del ratón se convierta en un poco ocupado en indicadores y luego nada. Puedo pasar por el método o hacer algo como esto

bool? shown = ofd.ShowDialog(); 

Pero pase lo que pase, el cuadro de diálogo no se mostrará. Por supuesto, se mostrará será falso en ese caso. Perdí una hora y media buscando ayer y justo cuando dejé de intentarlo de nuevo y de repente funcionó. A veces funciona, a veces no funciona. Pero parece ser específico del proyecto porque puedo pegar el mismo código en un nuevo proyecto y funciona como se supone que debe hacerlo. Además, eso es lo único del proyecto que parece sospechoso. Todo lo demás funciona según lo previsto.

¿Alguien aquí ha experimentado alguna vez algo similar y, por lo tanto, una idea de qué diablos podría hacer? Cualquier ayuda sería muy apreciada.

+4

Como punto de referencia para aquellos que responden, esto parece ser 'Microsoft.Win32.OpenFileDialog' y no el equivalente' System.Windows.Forms.OpenFileDialog'. –

+0

Sí, así es, gracias por la aclaración. – Koarl

+0

Es una vieja pregunta, pero estoy experimentando el mismo fenómeno con un complemento de VSTO para Excel: "A veces funciona, otras veces no". Es totalmente impredecible. Desafortunadamente, ni experimentar con hilos de STA ni crear formularios (ficticios) o ventanas de WPF antes de llamar a OpenFileDialog.ShowDialog() (como se sugiere a continuación) previene este comportamiento. – bovender

Respuesta

7

Hay una gran cantidad de posibles modos de falla para OpenFileDialog. Al usar uno, expone su aplicación a casi cualquier extensión de shell que esté instalada en su máquina. Muchos de los cuales pueden ser muy desestabilizadores, no es probable que el autor de la extensión haya verificado si funciona correctamente en un proceso de WPF.

Solucione este problema ejecutando la utilidad AutoRuns de SysInternals. Haga clic en la pestaña Explorador y busque los grupos que tienen "ShellEx" en su nombre. Desmarque cualquier cosa que no haya sido publicada por Microsoft. Reinicie y verifique si el problema está resuelto.

+0

¡Gracias por el consejo! Lamentablemente, como señaló, hay una gran cantidad de posibles modos de falla y la desactivación de todas las extensiones de shell de terceros no fue la que encontré. Incluso después de apagar todo y reiniciar el problema, persiste. Además, permítanme señalar que los diálogos funcionan en otro proyecto al mismo tiempo, sin problemas. Sin embargo, me gustaría votar tu respuesta, ya que me parece bastante útil. Lamentablemente no puedo hacer eso hasta que reuní más representantes: P – Koarl

6

Esto me ha pasado recientemente. El problema fue que el método Main no se marcó como STAThread, lo que hará que el método ShowDialog de WPF OpenFileDialog se bloquee indefinidamente.

static void Main(string[] args) 
{ 
    var openFileDialog = new OpenFileDialog(); 
    var result = openFileDialog.ShowDialog(); 
} 

nunca lo hará de salida o lanzar una excepción, mientras que

[STAThread]  
static void Main(string[] args) 
{ 
    var openFileDialog = new OpenFileDialog(); 
    var result = openFileDialog.ShowDialog(); 
} 

funcionará como se espera.

+0

¿Al decir que bloqueará significa que no volverá? Porque eso claramente no es lo que está sucediendo en mi extremo. Por el contrario, vuelve inmediatamente, lo que indica que no se mostró Diálogo pero solo lo hace en ocasiones aleatorias. – Koarl

+0

En la aplicación de consola, es necesario tener STAThread para que funcione el cuadro de diálogo. –

+0

Pero WPF es diferente. Y el código parece estar ejecutándose en el hilo principal también. –

0

No estoy seguro si lo has entendido o no, pero recientemente tuve el mismo problema. En mi caso, el problema era que mi aplicación no había establecido una ventana existente.

Mi código se parecía a esto.

private void Application_Startup(object sender, StartupEventArgs e) { 
    string startupFileName = String.Empty(); 
    if (startupMode = StartupMode.Load) { 
     // open existing file 
     OpenFileDialog openDlg = new OpenFileDialog(); 
     if (openDlg.ShowDialog() != true) 
      return; 
     startupFileName = openDlg.FileName; 
    } else { 
     // create a new file 
     SaveFileDialog saveDlg = new SaveFileDialog(); 
     if (saveDlg.ShowDialog() != true) 
      return; 
     startupFileName = saveDlg.FileName; 
    } 

    // show my main application window 
    MainWindow myMainWindow = new MainWindow(startupFileName); 
    myMainWindow.Show(); 
} 

El OpenFileDialog (o SaveFileDialog) se vuelven inmediatamente sin mostrar falsa porque mi solicitud no tenía ventana para que pueda unirse a.

Mi solución fue poner el código de abrir/guardar después de crear la ventana principal, pero antes llamé al método Show().

+0

Ese no parece ser el problema con mi aplicación, ya que está garantizado que tendrá una ventana establecida al crear el diálogo. El usuario tiene que hacer clic en un botón para que aparezca, por lo que ** tiene ** para ser una ventana. ¿O no entendí tu respuesta? – Koarl

0

En la aplicación de consola, necesitará el apartamento STAThread para que funcione. Pero WPF es diferente.

Le aconsejaría que use los cuadros de diálogo de archivo solo después de que se inicie la ventana y el hilo principal comience a funcionar. Intente mostrar su cuadro de diálogo en algún evento MainWindow de su ciclo de vida.

1

Tengo un problema similar, y como sugirió Garrett, es un problema de STA. He estado luchando con problemas de STA en los últimos meses, ya que necesito iniciar pantallas desde la ventana de la consola (fines de prueba): esto significa que el hilo de llamada no es STA, pero se puede simular de la siguiente manera:

[STAThread] 
    private void Execute() { 
     try { 
      Thread t = new Thread(() => { 
       OpenFileDialog dlg = new OpenFileDialog(); 
       // The following would not return the dialog if the current 
       // thread is not STA 
       var result = dlg.ShowDialog(); 
      }); 

      t.SetApartmentState(ApartmentState.STA); 
      t.Start(); 
     } catch (Exception ex) { 
      // Handle the exception 
      ex.LogException(); 
     } 
    } 

Unforunately, no funcionó para mí acaba de indicar el método como STAThread, tenía que lanzar la operación en un hilo marcado como STA.

+0

Esto es exactamente lo que me ayudó, ¡gracias! Y sí, solo marcar el método con la propiedad STAThread no fue suficiente. – user2134488

1

Sé que esta pregunta fue hecha en 2010 y la respuesta directa no fue la que voy a proporcionar, pero como la fecha de hoy hay otra razón para tener este problema.

Recientemente instalé mi software en una nueva máquina virtual que funciona perfectamente en mi computadora dev y muchas otras máquinas de prueba.

La máquina virtual Windows 7 era demasiado dulce y no tenía el KB976932 SP1 instalado.

Una vez instalado, podría usar los diálogos de guardar archivos de arena abiertos.

Espero que esto ayude a alguien más.