C# OpenFileDialog 非モーダル可能
-
20-08-2019 - |
質問
非モーダルな .net OpenFileDialog を作成または使用することは可能ですか。メイン ダイアログに UI 要素があり、ユーザーが常に押すことができるようにする必要があります。
解決
いいえ、 ファイルを開くダイアログ そして ファイルの保存ダイアログ どちらもから派生しています ファイルダイアログ, 、これは本質的にモーダルであるため、(私の知る限り) どちらの非モーダル バージョンを作成する方法もありません。
他のヒント
あなたはスレッドを作成し、スレッドのホストOpenFileDialogを持つことができます。サンプルコードは、同期のいずれかの種類を欠いているが、それは動作します。
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();
}
}
このコードを使用すると、あなたのUIスレッドでイベントを発生するために何かを追加することができます(呼び出しに注意してください!)彼らが完了したら、知っています。あなたは、
により、ダイアログの結果にアクセスすることができますDialogResult a = ofdThread.DialogResult
あなたのUIスレッドから。
私は少し遅れています知っていますが、新しいフォーム、ボーダレス、透明またはディスプレイ境界外を作成し、そのウィンドウを改造ファイルダイアログが表示される場合があります。
これは、古いポストですが、私は(「文脈」と完全しかし、簡略化のコードで)私はここに提示したい結果に到達した2日間を過ごします @Joshuaさんの答えは(私が.ConfigureAwait(真)に真入れると最後で、最初のコードサンプルを参照してください)私のために働きました。たぶん私は、MSDNの長い記事<のhref =「https://msdn.microsoft.com/en-us/library/ms741870(v=vs.110).aspx」のrel =」に基づいて、以下の行を記述することができましたnoreferrer nofollowを ">スレッドモデルは、私はまだもう一度読む必要があることします。
私のコンテキストは、WPF(基本MVVM)であり、私は(データグリッドの)いくつかの.CSVバックアップを書き込むために、ファイルを選択する必要があります。 Iは、(メンバ)関数は、非ブロッキングのFileDialog
と非同期でChooseFileFromExtension()
ことが必要
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
}
}
}
と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;
}
}
fetcher.BeginInvoke()
起動(非同期)SaveFileDialog
ShowDialog()
別のスレッドで、彼らは簡単なダイレクトであったであろうように、メインUIスレッド/ウィンドウ(...は++)どちらがブロックされても無効になっているように、 TaskCompletionSource<string> tcs
するために呼び出します。別の「単一」のスレッドによって、そのアクセスはOKですので<=> WPF UIオブジェクトではありません。
それはまだ私は、さらに研究する必要がある分野です。私は、件名には「究極」のドキュメント/本は(多分再びステファン・クリアリーから1のような本に2番目の外観を持つべきである)がない感じ。このコードは、少なくとも上に被覆トピックに改善されるべきである C-シャープ非同期コールなしで、EndInvokeをの
これは、名前空間Microsoft.Win32
ののFileDialogで動作します