DOBON.NETプログラミング掲示板過去ログ
WPF画面から別スレッドで起動したWindowsフォームの終了について
題名: WPF画面から別スレッドで起動したWindowsフォームの終了について
著者: KUROBOU
日時: 2008/11/27 14:27:10
ID: 23434
この記事の返信元:
(なし)
この記事への返信:
[23448]
Re[1]: WPF画面から別スレッドで起動したWindowsフォームの終了について
KUROBOU
2008/12/01 14:12:56
[解決]
ツリーを表示
環境/言語:[WindowsXP,C#,WPF]
分類:[.NET]
お世話になっております。
さて、メイン画面をWPFで作成し、そこから呼ばれる各画面(子画面)を
別スレッドで起動するようなプログラムを作成しようとしています。
なお、子画面はWindowsフォームで作成した画面になります。
メイン画面の機能としては
1.あるボタンを押下したら子画面を別スレッドで起動する
2.あるボタンを押下したら起動している子画面を全て終了させて
メイン画面のみ残す
という機能を持たせたいのですが、子画面のCloseでエラーが発生しています。
※エラー「有効ではないスレッド間の操作: コントロールが作成された
スレッド以外のスレッドからコントロール 'Form1' がアクセスされました。」
メイン画面もWindowsフォームで作成した場合は、うまくいったので
違う箇所としては、「button2_Click」内にあるInvokeの記述が
WPFフォーム this.Dispatcher.Invoke
Winフォーム this.Invoke
となっているだけです。
多少の文法の違いはあってもそのままロジックは移行できると思っていたの
ですが、何が悪いのでしょうか?
分かる方があられましたら教えていただけないでしょうか?
よろしくお願いします。
・今回のテストロジック
WPFアプリケーション作成で、Windowsフォームを追加した状態です
namespace WpfApplication1
{
/// <summary>
/// Window1.xaml の相互作用ロジック
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
//
// button1イベント(別スレッドで画面を起動する)
//
private void button1_Click(object sender, RoutedEventArgs e)
{
ThreadShowForm();
}
//
// button2イベント(別スレッドで起動した画面をWPF画面より終了させる)
//
private void button2_Click(object sender, RoutedEventArgs e)
{
// すべての画面を閉じる
for (int i = Window_Forms.Application.OpenForms.Count - 1; i >= 0; i--)
{
Form frm = Window_Forms.Application.OpenForms[i];
try
{
if (frm is Form1)
{
//スレッドで呼び出した画面を閉じる
this.Dispatcher.Invoke(new System.EventHandler(InvokeCloseForm), frm, null);
}
}
catch (Exception Ex)
{
System.Windows.MessageBox.Show(Ex.Message);
}
}
}
//
// 別スレッドでWindowsFormを起動する
//
private void ThreadShowForm()
{
try
{
Thread thread = new Thread(new ParameterizedThreadStart(StartKinouThread));
thread.Start(thread);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Source + " :\n " + ex.Message);
}
}
public void StartKinouThread(object thread)
{
try
{
ShowForm();
Thread currentThread = thread as Thread;
// 画面閉じた処理
// スレッド中止
if (currentThread != null)
{
if (currentThread.ThreadState != System.Threading.ThreadState.Aborted)
{
//currentThread.Join();
currentThread.Abort();
}
}
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Source + " :\n " + ex.Message);
}
}
//
// WindowsFormの起動
//
private void ShowForm()
{
Form1 frm = new Form1();
frm.Text = frm.Handle.ToString();
frm.ShowDialog();
}
private void InvokeCloseForm(object sender, System.EventArgs e)
{
//今の画面を取得する
Form1 frm = sender as Form1;
//画面を閉じる
frm.Close();
}
}
}
題名: Re[1]: WPF画面から別スレッドで起動したWindowsフォームの終了について
著者: KUROBOU
日時: 2008/12/01 14:12:56
ID: 23448
この記事の返信元:
[23434]
WPF画面から別スレッドで起動したWindowsフォームの終了について
KUROBOU
2008/11/27 14:27:10
この記事への返信:
(なし)
ツリーを表示
お世話になります。
自己解決しました。
button2_Click 内の
this.Dispatcher.Invoke を frm.Dispatcher.Invoke
に変更したらうまくいきました。
大変申し訳ございませんでした。
解決済み!
DOBON.NET
|
プログラミング道
|
プログラミング掲示板
分類:[.NET]
お世話になっております。
さて、メイン画面をWPFで作成し、そこから呼ばれる各画面(子画面)を
別スレッドで起動するようなプログラムを作成しようとしています。
なお、子画面はWindowsフォームで作成した画面になります。
メイン画面の機能としては
1.あるボタンを押下したら子画面を別スレッドで起動する
2.あるボタンを押下したら起動している子画面を全て終了させて
メイン画面のみ残す
という機能を持たせたいのですが、子画面のCloseでエラーが発生しています。
※エラー「有効ではないスレッド間の操作: コントロールが作成された
スレッド以外のスレッドからコントロール 'Form1' がアクセスされました。」
メイン画面もWindowsフォームで作成した場合は、うまくいったので
違う箇所としては、「button2_Click」内にあるInvokeの記述が
WPFフォーム this.Dispatcher.Invoke
Winフォーム this.Invoke
となっているだけです。
多少の文法の違いはあってもそのままロジックは移行できると思っていたの
ですが、何が悪いのでしょうか?
分かる方があられましたら教えていただけないでしょうか?
よろしくお願いします。
・今回のテストロジック
WPFアプリケーション作成で、Windowsフォームを追加した状態です
namespace WpfApplication1
{
/// <summary>
/// Window1.xaml の相互作用ロジック
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
//
// button1イベント(別スレッドで画面を起動する)
//
private void button1_Click(object sender, RoutedEventArgs e)
{
ThreadShowForm();
}
//
// button2イベント(別スレッドで起動した画面をWPF画面より終了させる)
//
private void button2_Click(object sender, RoutedEventArgs e)
{
// すべての画面を閉じる
for (int i = Window_Forms.Application.OpenForms.Count - 1; i >= 0; i--)
{
Form frm = Window_Forms.Application.OpenForms[i];
try
{
if (frm is Form1)
{
//スレッドで呼び出した画面を閉じる
this.Dispatcher.Invoke(new System.EventHandler(InvokeCloseForm), frm, null);
}
}
catch (Exception Ex)
{
System.Windows.MessageBox.Show(Ex.Message);
}
}
}
//
// 別スレッドでWindowsFormを起動する
//
private void ThreadShowForm()
{
try
{
Thread thread = new Thread(new ParameterizedThreadStart(StartKinouThread));
thread.Start(thread);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Source + " :\n " + ex.Message);
}
}
public void StartKinouThread(object thread)
{
try
{
ShowForm();
Thread currentThread = thread as Thread;
// 画面閉じた処理
// スレッド中止
if (currentThread != null)
{
if (currentThread.ThreadState != System.Threading.ThreadState.Aborted)
{
//currentThread.Join();
currentThread.Abort();
}
}
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Source + " :\n " + ex.Message);
}
}
//
// WindowsFormの起動
//
private void ShowForm()
{
Form1 frm = new Form1();
frm.Text = frm.Handle.ToString();
frm.ShowDialog();
}
private void InvokeCloseForm(object sender, System.EventArgs e)
{
//今の画面を取得する
Form1 frm = sender as Form1;
//画面を閉じる
frm.Close();
}
}
}