0

私のwpfアプリケーションでは、UIがユーザーに応答するように、ボタンクリックイベントを別のスレッドとして作成し、バックグラウンドプロセスとして実行しました。以下のようなコード、

private void btn_convert_Click(object sender, RoutedEventArgs e)
{
   //Makes the conversion process as background task which 
   //makes the UI responsive to the user.
   Thread thread = new Thread(new ThreadStart(WorkerMethod));
   thread.SetApartmentState(ApartmentState.MTA);
   thread.IsBackground = true;
   thread.Start();
}

WorkerMethod では、ユーザーに別のウィンドウを提供しているファイル名を変更するオプションがあります。このアクションでは、以下のように Dispatcher メソッドを使用しています。

if (MessageBox.Show("Do you want to set filename?", 
    "Information", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == 
    MessageBoxResult.Yes)
{                         
    Action showOutput = () =>
    { 
        BlueBeamConversion.SetOutput _setOutput = 
            new BlueBeamConversion.SetOutput(); 
        _setOutput.ShowDialog();
    }; 

    Dispatcher.BeginInvoke(showOutput);

    if (String.IsNullOrEmpty(MainWindow.destinationFileName))
              return;

ここで、destinationFileName は SetOutput ウィンドウで設定されます。上記のコードを実行すると SetOutput ウィンドウが表示され、ファイル名を設定するまで待機しません。ファイル名を設定する前に、以下のコードになります。

if (String.IsNullOrEmpty(MainWindow.destinationFileName))
                                return;

setoutputウィンドウで[OK]ボタンをクリックするまでどうすれば保持できますか。どんな提案でも大歓迎です。

BeginInvoke の代わりに、dispatcher.Invoke を使用しました。これでウィンドウが保持され、新しい名前が付けられます。ただし、workmethod のコードを特定の行で継続すると、アプリケーション自体が終了します。以下のコードを修正してください。

if (MessageBox.Show("Do you want to set filename?", "Information", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes)
                    {

                        Action showOutput = () =>
                        { BlueBeamConversion.SetOutput _setOutput = new BlueBeamConversion.SetOutput();  _setOutput.ShowDialog(); }; 
                       Dispatcher.Invoke(showOutput);

                    for (int i = 0; i < _listFiles.Items.Count; i++)--- here it exits
                {--------- }

よろしくサンギータ

4

4 に答える 4

1

BeginInvoke の代わりに Invoke を使用できます。

 //Dispatcher.BeginInvoke(showOutput);
 Dispatcher.Invoke(showOutput);
于 2013-03-18T09:01:32.317 に答える
1

Show() の代わりに ShowDialog() を使用し、出力を DialogResult に保存します

 var result = _setOutput.ShowDialog();
于 2013-03-18T08:58:59.433 に答える
0

アクションで window.show() メソッドを使用している間は、show メソッドから結果を受け取ることはありません。代わりに、ウィンドウの show dialog メソッドを呼び出す必要があります。これにより、ダイアログ ウィンドウが閉じられるまで GUI が保持されます。ダイアログウィンドウからデータを受け取ることができます。

 Action showOutput = () =>
                            { BlueBeamConversion.SetOutput _setOutput = new BlueBeamConversion.SetOutput(); _setOutput.ShowDialog(); }; 
                        Dispatcher.BeginInvoke(showOutput);

一方、スレッドが最初に完了するのを待ってから、待つことができます。このアプローチはあなたにも役立ちます。dispatcher.Invoke が役に立ちます。または、ここで DispatcherOperation を試すこともできます。

以下の変更されたコードで試してください。

  DispatcherOperation op = Dispatcher.BeginInvoke(showOutput);

                op.Wait();

                if (String.IsNullOrEmpty(output))
                    return;
于 2013-03-18T09:02:13.103 に答える
0

ShowDialog を使用する場合、2 番目のウィンドウのパブリック プロパティに値を格納し、次のような方法でアクセスできます。

Form2 form2 = new Form2();
if (form2.ShowDialog() == DialogResult.OK)
{
if (form2.ReturnData == "myResult")

... }

于 2013-03-18T09:03:42.647 に答える