Frage

Ist es möglich, ein nicht modales .NET OpenFiledialog zu erstellen/zu haben? Ich habe ein UI-Element im Hauptdialog, das für den Benutzer immer verfügbar sein muss.

War es hilfreich?

Lösung

Nein, OpenFiledialog und SaveFiledialog sind beide abgeleitet von FileDialog, was von Natur aus modal ist, also (soweit ich weiß) gibt es keine Möglichkeit, eine nicht modale Version von beiden zu erstellen.

Andere Tipps

Sie können einen Thread erstellen und den Thread -Host den OpenFiledialog haben. Der Beispielcode fehlt irgendeine Art von Synchronisation, funktioniert jedoch.

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

Mit diesem Code könnten Sie etwas hinzufügen, um ein Ereignis in Ihrem UI -Thread zu entlassen (vorsichtig mit dem Aufrufen!), Um zu wissen, wann sie fertig sind. Sie können auf das Ergebnis des Dialogs zugreifen

DialogResult a = ofdThread.DialogResult

Aus Ihrem UI -Thread.

Ich weiß, dass ich etwas spät dran bin, aber Sie können ein neues Formular erstellen, randlos, transparent oder außerhalb der Anzeigegrenzen und das Dateidialog anzeigen, das dieses Fenster modifiziert.

Es ist ein alter Beitrag, aber ich verbringe 2 Tage damit, das Ergebnis zu erreichen, das ich hier präsentieren möchte (mit "Kontext" und vollständiger, aber vereinfachter Code). siehe Erstcode -Beispiel). Vielleicht konnte ich weniger Zeilen basierend auf dem langen Artikel von MSDN schreiben Threading -Modell Das muss ich noch einmal lesen.

Mein Kontext ist WPF (Basic MVVM) und ich muss eine Datei auswählen, um eine .csv -Sicherung (eines Datagrids) zu schreiben. Ich brauche das (Mitglied) Funktion ChooseFileFromExtension() asynchron sein mit einem nicht blockierenden Fachangaben

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

und der Code für MyFiledialog -Klasse

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

Das fetcher.BeginInvoke() startet (asynchron) die SaveFileDialog ShowDialog() in einem anderen Thread, so dass das Haupt -UI -Thread / Fenster (... ++) weder blockiert noch deaktiviert ist ShowDialog(). TaskCompletionSource<string> tcs ist kein WPF -UI -Objekt, daher ist sein Zugriff nach einem anderen "Single" -Thread in Ordnung.

Es ist immer noch ein Feld, das ich weiter studieren muss. Ich habe das Gefühl, dass es keine "ultimative" Dokumentation/Buch zu diesem Thema gibt (vielleicht sollte es einen zweiten Blick auf Bücher wie die von Stephen Cleary wieder haben). Dieser Code sollte zumindest mit einem Thema verbessert werden c-sharp-asynchron-call-gout-out-Endinvoke

Es arbeitet mit dem Montage -Namenspace Microsoft.Win32

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top