分類:[C#]
2017/07/05(Wed) 19:18:25 編集(投稿者)
初めましてKLと申します。
現在大学の研究の一環としてプログラミングをVisualStudio2017のC#で行っておりどうしてもわからないことがあり投稿させていただきます。
クラスを生成しその中にSystem.Timers.Timerを持たせ、
そのタイマーがカウントするごとにクラスの中で生成したPictureBoxを移動させたいのですがうまくいきません。
以下のようなコード書いたのですが実行しボタンを押すと
「System.InvalidOperationException:
'有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'pictureBox1' がアクセスされました。'」
というエラーが出てきます。
また自分なりに調べてみるとタイマーにより別スレッドが作成されそこからではコントロールにアクセスできないということがわかり、
delegateやInvokeを使うことも試してみましたが
「System.InvalidOperationException:
'ウィンドウ ハンドルが作成される前、コントロールで Invoke または BeginInvoke を呼び出せません。'」
というエラーが出てしまいます。
解決策やヒントをいただければ幸いです。よろしくお願いします。
//以下ソースコード----------------------------------------------------------------------
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Timers;
namespace WindowsFormsApp
{
public partial class Form1 : Form
{
Class1 move = new Class1();
public Form1()
{
InitializeComponent();
move = new Class1 { myPictureBox = pictureBox1 };
move.NewTimer();
}
private void button1_Click(object sender, EventArgs e)
{
move.myTimer1.Start();
}
}
public class Class1 :Form
{
public PictureBox myPictureBox;
public System.Timers.Timer myTimer1;
public void NewTimer()
{
myTimer1 = new System.Timers.Timer();
myTimer1.Enabled = false;
myTimer1.AutoReset = true;
myTimer1.Interval = 100;
myTimer1.Elapsed += new ElapsedEventHandler(OnTimerEvent1);
}
public void OnTimerEvent1(object source, ElapsedEventArgs e)
{
MovePictureBox();
}
//delegate void MoveDelegate();
public void MovePictureBox()
{
/*if(myPictureBox.InvokeRequired)
{
Invoke(new MoveDelegate(MovePictureBox));
return;
}*/
Point p;
p = myPictureBox.Location;
p.X += 10;
myPictureBox.Location = p;
}
}
}
追記:
説明不足な点がいくつかありましたので追記させていただきます。
・このコードを書く前にWindows.Form.Timerの方で正常に動作することは確認しました。
・コメントにてInvokeとdelegateを使ったときのコードを加えました。