Is it possible to create/have a non-modal .net OpenFileDialog I have a UI element in the main dialog which always need to be available for the user to press.
问题:
回答1:
No, OpenFileDialog and SaveFileDialog are both derived from FileDialog, which is inherently modal, so (as far as I know) there's no way of creating a non-modal version of either of them.
回答2:
You can create a thread and have the thread host the OpenFileDialog. Example code is lacking any kind of synchronization but it works.
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();
}
}
With this code you could add something to fire an event in your UI thread (be careful with invoking!) to know when they're done. You can access the result of the dialog by
DialogResult a = ofdThread.DialogResult
from your UI thread.
回答3:
I know I am a little late but you may create a new form, borderless, transparent or outside the display bounds and show the file dialog modding that window.
回答4:
It is an old post but I spend 2 days reaching the result I want to present here ( with "context" and complete but simplified code ) @Joshua 's answer worked for me ( at last when I put true to .ConfigureAwait(true), see first code sample). Maybe I was able to write less lines based on the long article of MSDN Threading Model that I still need to read once again.
My context is WPF ( basic MVVM ) and I must choose a file in order to write some .CSV backup ( of a datagrid ). I need that the (member) function ChooseFileFromExtension()
be asynchronous with a non-blocking FileDialog
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
}
}
}
and the code for MyFileDialog class
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;
}
}
The fetcher.BeginInvoke()
launches (asynchronously) the SaveFileDialog
ShowDialog()
in another thread so that the main UI Thread / Window (...++) are neither blocked nor disabled as they would have been with a simple direct call to ShowDialog()
. TaskCompletionSource<string> tcs
is not an WPF UI Object so its access by another "single" thread is OK.
It is still a field that I need to study further. I feel there is no "ultimate" documentation/book on the subject ( maybe should have a second look to books like the one from Stephen Cleary again). This code should be improved at least with topic covered on c-sharp-asynchronous-call-without-endinvoke
It works with the FileDialog of namespace Microsoft.Win32