|
ご無沙汰しています。先日魔界の仮面弁士さんが送ってくださったコードを少し変え、
チェックボックスではなく「ボタンをクリックしたら描画される」ようにしました。以下のようにしました。
private void button1_Click(object sender, EventArgs e)
{
panel2.Paint += panel2_Paint;
panel2.Invalidate();
}
そうしたところ、ボタンをクリックをした後、ちゃんと描画されましたし、再描画も問題ありませんでした。
これを元に、自分自身が作りたいコードにも同じようにpanel2.Invalidate();を使って再描画を試みましたが、
どうしても、「一瞬だけ描画され、すぐに画面から全てが消えてしまう」ようになってしまいます。
上記のボタンクリックの場合と同じように、以下のようにpanel2.Invalidate();を使いました。
private void button1_Click(object sender, EventArgs e)
{
//座標値を得て、描画をさせるメソッドを呼び出す
this.myDraw.DrawMovingObjects();
panel2.Invalidate();
}
Invalidate();の一行なしでコードを走らせると、描画はされますが、画面をスクロールすると、
それまで描画されていなかった部分は表示されません。
画面をスクロールしてから再びボタンを押すと、パネルに写っている部分については再描画がされます。
また、Invalidate()を使う位置をいろいろと変えてみましたが、やはり、描画され、すぐに消えてしまいます。
Invalidate()の使い方が根本的に間違っているのでしょうか。
私のコードの場合、デリゲートを使っていますが、それが関係しているのでしょうか。
以下に再びコードをお知らせします。
お手数ですが、アドバイスをいただけると嬉しいです。よろしくお願いします。
なお、描画に使う座標値は、新たにMovingPointというクラスを作りました。
MovingPointにはID、x座標、y座標をフィールドとして作成し、
MovingPoint型のmPointというインスタンスを作成し、そこに座標値を格納しました。
さらに、そのmPointを格納するArrayList mPointsをつくり、
mPoints.Add(mPoint);というふうに、全てのmPointをArrayListの中に格納しました。
このArrayListであるmPointsをイベントハンドラの中で使用し、座標を取り出し、折れ線を描いています。
【DrawingMODクラスのコード】
public delegate void DrawOnPanel(object sender, PaintEventArgs e, ArrayList mPoints);//デリゲート
class DrawingMOD
{
public event DrawOnPanel DrawPolyline; //イベントフィールド
private Control m_control;
//コンストラクタ
public DrawingMOD(Control c)
{
this.m_control = c;
}
//パネルに折れ線を描画するメソッド
public void DrawMovingObjects()
{
//変数を定義
int tID = 0;
float xCo = 200.01f;
float yCo = 200.01f;
//ID, x座標,y座標を格納するMovingPointクラスのオブジェクトを格納するArrayListを作成
ArrayList mPoints = new ArrayList();
for (int i = 0; i < 3; i++)
{
//ID, x座標,y座標を格納するMovingPointクラスのオブジェクト
MovingPoint mPoint = new MovingPoint();
//ID, x座標,y座標をmPointに入れる
mPoint.TrackID = tID;
mPoint.XCoordinate = xCo;
mPoint.YCoordinate = yCo;
//mPointをArrayListであるmPointsに格納する
mPoints.Add(mPoint);
//ID, x座標,y座標の値を変える
tID++;
xCo += 70;
yCo += 50;
}
PaintEventArgs e = new PaintEventArgs(m_control.CreateGraphics(), m_control.ClientRectangle);
//イベントを発生させる
this.DrawPolyline(this.m_control, e, mPoints);
//再描画を試みる
//this.m_control.Invalidate();
}
}
【Form1のコード】
public partial class Form1 : Form
{
DrawingMOD myDraw; //Form1で共通に使用するオブジェクト変数の宣言
Panel panel1 = new Panel();
Panel panel2 = new Panel();
public Form1()
{
InitializeComponent();
//panel1、panel2のプロパティ
panel1.AutoScroll = true;
panel1.Dock = DockStyle.Fill;
panel2.AutoSize = true;
panel2.Size = new Size(1000, 1000);
panel2.Location = Point.Empty;
panel1.Controls.Add(panel2);
this.Controls.Add(panel1);
this.Size = new Size(400, 400);
this.myDraw = new DrawingMOD(this.panel2);
//イベントとイベントハンドラを関連づける
myDraw.DrawPolyline += new DrawOnPanel(myDraw_DrawPanel);
}
private void button1_Click(object sender, EventArgs e)
{
//座標値を得て、描画をさせるメソッドを呼び出す
this.myDraw.DrawMovingObjects();
//再描画を試みる
//panel2.Invalidate();
}
//myDraw_DrawPanelイベントハンドラ
private void myDraw_DrawPanel(object sender, PaintEventArgs e, ArrayList mPoints)
{
//背景色を設定
e.Graphics.Clear(Color.Black);
//ペンの色を定義
int cRed = 200;
int cGreen = 100;
int cBlue = 100;
//描画をするためのPointFの配列を用意
PointF[] myPoints = new PointF[mPoints.Count];
foreach (MovingPoint m in mPoints)
{
//myPointsにmPointsの座標を入れる
myPoints[m.TrackID] = new PointF(float.Parse(m.XCoordinate.ToString()), float.Parse(m.YCoordinate.ToString()));
}
//ペンを作成
using (Pen pen = new Pen(Color.FromArgb(cRed, cGreen, cBlue), 4))
{
//折れ線を矢印にする
pen.EndCap = LineCap.ArrowAnchor;
//折れ線を描く
e.Graphics.DrawLines(pen, myPoints);
}
}
}
|