2016-02-09 14 views
5

DevExpressでC#を使用する方法を学習するためにHangManゲームを設計しています。 私の問題は、私がそれを描いているパネルのサイズに相対的なサイズのポストを描画しているので、ウィンドウのサイズを変更するとそのサイズが再計算されるということです。私のコードは次のようになります:ウィンドウが最大化されるとイメージが複製されます

namespace HangMan 
{ 
    public partial class HangMan : Form 
    { 
    public HangMan() 
    { 
     InitializeComponent(); 
     this.Paint += new System.Windows.Forms.PaintEventHandler(HangMan_Paint); 
    } 

    void drawHangPost() 
    { 

     //Use panel size percentages to draw the post 
     double dWidth = pnlHang.Width; double dHeight = pnlHang.Height; 

     int x1 = (int)Math.Round(0.8 * dWidth); int x2 = (int)Math.Round(0.45 * dWidth); 
     int y1 = (int)Math.Round(dHeight); int y2 = (int)Math.Round(0.23 * dHeight); 
     int xInit = x1; int xFinal = x1 - x2; 
     int yInit = y1; int yMiddle = 10; int yFinal = y2; 

     //Paint Post 
     Graphics g = pnlHang.CreateGraphics(); 
     Pen p = new Pen(Color.Brown, 10); 

     g.DrawLine(p, new Point(xInit, yInit), new Point(xInit, yMiddle)); 
     g.DrawLine(p, new Point(xInit, yMiddle), new Point(xFinal, yMiddle)); 
     g.DrawLine(p, new Point(xFinal, yMiddle), new Point(xFinal, yFinal));  
    } 

    private void HangMan_Paint(object sender, EventArgs e) 
    { 
     drawHangPost(); 
    }   
    } 
} 

これは私のために完全に動作し、投稿図面のサイズが変更されます。しかし、私は手動でウィンドウのサイズを変更すると、新しい投稿が各ステップで描画されるので、それらの多くが表示されます。ウィンドウを最大化すると、2つの異なるサイズの2つのポストが表示されます。

しかし、私がウィンドウを最小化して再び開くと、正しい描画だけが残ります。新しい図面が描かれたときに以前の図面を消滅させる方法はありますか?

の後にeraisingコマンド書き込みを含めるべきですか?InitializeComponent()

+2

フォームのOnResizeイベントで 'pnlHang.Invalidate()'を試してください。 – SimpleVar

+3

@SimpleVarが言うように、または 'Control.ResizeRedraw'プロパティを使用してください - – adv12

+0

@ adv12それは良いプロパティです、それを知らなかった - thx! :D – SimpleVar

答えて

4

は、だからあなたの問題の大部分は、フォームのPaintイベントに応答して、または無効にされていない可能性があり制御に塗装しています。

代わりに、パネルのペイントイベントに登録して、イベント引数に渡されるGraphicsオブジェクトを使用してペイントしてください。また、パネルのサイズ変更イベントを無効にするために、パネルのresizeイベントを処理する必要があります。フォームのサイズを変更したときにパネルのサイズを自動的に変更するためにアンカーまたはドッキングを使用していると仮定しています。そうでない場合は、フォームが変更されたときにパネルのサイズが変更されるように変更する必要があります。

public Form1() 
    { 
     InitializeComponent(); 

     pnlHang.Paint += PnlHangPaint; 
     pnlHang.Resize += (sender, args) => pnlHang.Invalidate(); 
    } 

    private void pnlHang_Paint(object sender, PaintEventArgs paintEventArgs) 
    { 
     drawHangPost(paintEventArgs.Graphics); 
    } 

    void drawHangPost(Graphics g) 
    { 
     //Use panel size percentages to draw the post 
     double dWidth = pnlHang.Width; 
     double dHeight = pnlHang.Height; 

     int x1 = (int)Math.Round(0.8 * dWidth); 
     int x2 = (int)Math.Round(0.45 * dWidth); 
     int y1 = (int)Math.Round(dHeight); 
     int y2 = (int)Math.Round(0.23 * dHeight); 
     int xInit = x1; 
     int xFinal = x1 - x2; 
     int yInit = y1; 
     int yMiddle = 10; 
     int yFinal = y2; 

     //Paint Post 
     using (Pen p = new Pen(Color.Brown, 10)) 
     { 
      g.DrawLine(p, new Point(xInit, yInit), new Point(xInit, yMiddle)); 
      g.DrawLine(p, new Point(xInit, yMiddle), new Point(xFinal, yMiddle)); 
      g.DrawLine(p, new Point(xFinal, yMiddle), new Point(xFinal, yFinal)); 
     } 
    } 

また、ペンやブラシのようなGDIリソースを作成するときは、必ずそれらを廃棄してください!ブロックを使用してC#はあなたのためにうまくいく。

+0

これはうまく動作し、コードはより整理されています。ありがとう、私は答えから多くを学んだ! @エリック – Slash

-1

問題は、同じコントロールの上に何度も繰り返し描画していることです。簡単な解決策は、前の画像を描画する矩形を塗りつぶすことです。これはフレームを頻繁に点滅させるので、私はそれを解決するために新しいビットマップを作成し、それを描画することです。次に、コンパイルしたビットマップをパネルに描画します。

public void Draw(Graphics g){ 
Bitmap canvas = new Bitmap(pnlHang.Width, pnlHang.Height); 
Graphics canvg = Graphics.FromImage(canvas); 
canvg.FillRectangle(Brushes.Black, new Rectangle(new Point(0, 0), pnlHang.Size); 
//Draw using canvg 
canvg.Dispose(); 
g.DrawImage(canvas, new Rectangle(new Point(0, 0), pnlHang.Size)); 
} 
+1

これは役に立たないでしょう。以前のグラフィックスが上書きされない理由は、コントロールの一部だけが無効にされているためです。 'Paint'イベントを処理するとき、あなたがする描画は、無効化された矩形にクリップされます。さらに、あなたが試みているようなダブルバッファリングが必要な場合は 'Control'クラスが組み込まれています。コントロールの' DoubleBuffered'プロパティと 'Paint 'で取得した' Graphics'オブジェクトを設定するだけです'はバックバッファ用です。 – adv12

+0

それは非常に興味深いです。ありがとう。 – frogmannick

関連する問題