Pregunta

¿Es posible crear / tener un .NET OpenFileDialog no modal? Tengo un elemento de IU en el diálogo principal que siempre debe estar disponible para que el usuario presione.

¿Fue útil?

Solución

No, OpenFileDialog y SaveFileDialog ambos se derivan de FileDialog , que es inherentemente modal, por lo que yo sé. no hay forma de crear una versión no modal de ninguno de ellos.

Otros consejos

Puede crear un hilo y hacer que el hilo aloje el 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, podría agregar algo para activar un evento en su subproceso de interfaz de usuario (¡tenga cuidado al invocar!) para saber cuándo terminaron. Puede acceder al resultado del diálogo

DialogResult a = ofdThread.DialogResult

de su hilo de UI.

Sé que llego un poco tarde, pero puede crear un nuevo formulario, sin bordes, transparente o fuera de los límites de la pantalla y mostrar el diálogo del archivo que modifica esa ventana.

Es una publicación antigua pero paso 2 días alcanzando el resultado que quiero presentar aquí (con " context " y código completo pero simplificado) La respuesta de @Joshua funcionó para mí (por fin cuando puse verdadero a .ConfigureAwait (verdadero), vea el primer ejemplo de código). Tal vez pude escribir menos líneas basadas en el largo artículo de MSDN Modelo de subprocesos que todavía necesito leer una vez más.

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

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;
    }
}

El fetcher.BeginInvoke() lanza (asincrónicamente) el SaveFileDialog ShowDialog() en otro hilo para que el Hilo / Ventana principal de la IU (... ++) no estén bloqueados ni deshabilitados, ya que habrían estado con un simple directo llame al TaskCompletionSource<string> tcs. <=> no es un objeto WPF UI por lo que su acceso por otro " single " el hilo está bien.

Todavía es un campo que necesito estudiar más. Siento que no hay & Quot; ultimate & Quot; documentación / libro sobre el tema (tal vez debería volver a mirar libros como el de Stephen Cleary nuevamente). Este código debe mejorarse al menos con el tema cubierto en c-sharp-asynchronous-call-without-endinvoke

Funciona con el FileDialog del espacio de nombres Microsoft.Win32

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top