Question

Est-il possible de créer / avoir un OpenFileDialog .net non modal? J'ai un élément d'interface utilisateur dans la boîte de dialogue principale qui doit toujours être disponible pour que l'utilisateur puisse appuyer dessus.

Était-ce utile?

La solution

Non, OpenFileDialog et SaveFileDialog sont tous deux dérivés de FileDialog , qui est intrinsèquement modal, donc (autant que je sache) il n'y a aucun moyen de créer une version non modale de l'un d'eux.

Autres conseils

Vous pouvez créer un thread et le héberger comme OpenFileDialog. Exemple de code manque de tout type de synchronisation, mais cela fonctionne.

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

Avec ce code, vous pouvez ajouter quelque chose pour déclencher un événement dans votre thread d'interface utilisateur (soyez prudent lorsque vous appelez!) pour savoir quand ils ont terminé. Vous pouvez accéder au résultat du dialogue par

DialogResult a = ofdThread.DialogResult

à partir de votre fil d'interface utilisateur.

Je sais que je suis un peu en retard, mais vous pouvez créer un nouveau formulaire, sans bordure, transparent ou en dehors des limites d'affichage, et afficher le dialogue de fichier moddant cette fenêtre.

C’est un article ancien, mais j’ai passé deux jours à atteindre le résultat que je souhaite présenter ici (avec & "contexte &" et code complet mais simplifié) La réponse de @Joshua a fonctionné pour moi (enfin, lorsque j'ai mis true dans .ConfigureAwait (true), voir le premier exemple de code). J'ai peut-être pu écrire moins de lignes sur la base du long article de MSDN Modèle de threading que je dois encore lire à nouveau.

Mon contexte est WPF (MVVM de base) et je dois choisir un fichier afin d'écrire une sauvegarde .CSV (d'une grille de données). J'ai besoin que la fonction (membre) ChooseFileFromExtension() soit asynchrone avec un FileDialog non bloquant

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

et le code de la classe 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;
    }
}

Le fetcher.BeginInvoke() lance (de manière asynchrone) le SaveFileDialog ShowDialog() dans un autre thread, de sorte que les threads / fenêtres de l'interface utilisateur principale (... ++) ne soient ni bloqués ni désactivés comme ils l'auraient été avec un simple accès direct. appel à TaskCompletionSource<string> tcs. <=> n'est pas un objet d'interface utilisateur WPF, donc son accès par un autre & "single &"; le fil est OK.

C’est toujours un domaine que j’ai besoin d’approfondir. Je pense qu’il n’existe pas de & «Ultimate &»; documentation / livre sur le sujet (peut-être devrait-il jeter un second regard sur des livres comme celui de Stephen Cleary). Ce code devrait au moins être amélioré avec la rubrique abordée dans appel c-sharp-asynchrone-sans-endinvoke

.

Cela fonctionne avec le FileDialog de l'espace de noms Microsoft.Win32

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top