2009-01-25 20 views

Respuesta

6

Puede crear un hilo y hacer que el hilo aloje OpenFileDialog. El código de ejemplo carece de cualquier tipo de sincronización, pero funciona.

public partial class Form1 : Form 
{ 
    OFDThread ofdThread; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     ofdThread = new OFDThread(); 
     ofdThread.Show(); 
    } 
} 

public class OFDThread 
{ 
    private Thread t; 
    private DialogResult result; 

    public OFDThread() 
    { 
     t = new Thread(new ParameterizedThreadStart(ShowOFD)); 
     t.SetApartmentState(ApartmentState.STA); 
    } 

    public DialogResult DialogResult { get { return this.result; } } 

    public void Show() 
    { 
     t.Start(this); 
    } 

    private void ShowOFD(object o) 
    { 
     OpenFileDialog ofd = new OpenFileDialog(); 
     result = ofd.ShowDialog(); 
    } 
} 

Con este código se podría añadir algo para disparar un evento en su hilo de interfaz de usuario (cuidado con la invocación!) Para saber cuando estén listas. Puede acceder al resultado del cuadro de diálogo

DialogResult a = ofdThread.DialogResult 

desde el hilo de su interfaz de usuario.

1

Sé que llego un poco tarde pero puede crear un nuevo formulario, sin márgenes, transparente o fuera de los límites de visualización y mostrar el cuadro de diálogo de modificación de esa ventana.

0

Es una publicación anterior pero paso 2 días alcanzando el resultado que quiero presentar aquí (con "contexto" y código completo pero simplificado) La respuesta de Josué funcionó para mí (al final cuando puse en verdad .ConfigureAwait (verdadero), vea el primer ejemplo de código). Tal vez pude escribir menos líneas basadas en el largo artículo de MSDN Threading Model que aún necesito leer una vez más.

Mi contexto es WPF (MVVM básico) y debo elegir un archivo para escribir algo de copia de seguridad .CSV (de una cuadrícula de datos). Necesito que la función (miembro) ChooseFileFromExtension() sea asíncrona con una FileDialog no bloqueante

class MainWindowExportToExcelCSV : ICommand 
{ 
    ... 
    public async void Execute(object parameter) 
    { 
     var usr_ctrl = parameter as UserControl; 
     MyFileDialog fd = new MyFileDialog(); 
     const bool WhenIComeBackIStillNeedToAccessUIObjectAndThusINeedToRetrieveMyOriginalUIContext = true; 
     string filename = await fd.ChooseFileFromExtension("CSV files (*.csv)|*.csv|All files (*.*)|*.*").ConfigureAwait(
      WhenIComeBackIStillNeedToAccessUIObjectAndThusINeedToRetrieveMyOriginalUIContext); 

     Visual visual = (Visual)usr_ctrl.Content; 
     for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++) 
     { 
      //look for datagrid element 
     } 
    } 
} 

y el código para la clase MyFileDialog

using Microsoft.Win32; 
... 

class MyFileDialog 
{ 
    //https://msdn.microsoft.com/en-us/library/ms741870(v=vs.110).aspx 
    //Article on Threading Model 
    private delegate void OneArgStrDelegate(string str); 

    private void MyExternalDialog(string extensions) 
    { 
     SaveFileDialog fd = new SaveFileDialog(); 
     fd.Filter = extensions; 
     fd.ShowDialog(); 
     tcs.SetResult(fd.FileName); 
    } 

    private TaskCompletionSource<string> tcs; 

    public Task<string> ChooseFileFromExtension(string file_ext) 
    { 
     //Cf Puppet Task in Async in C#5.0 by Alex Davies 
     tcs = new TaskCompletionSource<string>(); 

     OneArgStrDelegate fetcher = new OneArgStrDelegate(this.MyExternalDialog); 
     fetcher.BeginInvoke(file_ext, null, null); 
     return tcs.Task; 
    } 
} 

Los fetcher.BeginInvoke() lanzamientos (asíncrona) la SaveFileDialogShowDialog() en otro hilo por lo que el subproceso principal de la interfaz de usuario (UI)/ventana (... ++) no está bloqueado ni deshabilitado como hubiera sido con una simple llamada directa al ShowDialog(). TaskCompletionSource<string> tcs no es un objeto de interfaz de usuario de WPF, por lo que su acceso por otro subproceso "único" es correcto.

Todavía es un campo que necesito estudiar más. Siento que no hay documentación/libro "definitivo" sobre el tema (tal vez debería echarle un segundo vistazo a libros como el de Stephen Cleary nuevamente). Este código debe ser mejorado, al menos, con el tema tratado en c-sharp-asynchronous-call-without-endinvoke

Funciona con el espacio de nombres de FileDialog Microsoft.Win32