2016-06-14 4 views
1

私はビットマップを使用して円を描こうとしています。以前に描画された円を保存しながら、クリック位置に新しい円のビットマップを描画します。

マウスをクリックするたびに、以前に描いた円Iが新しい位置に移動します。

私がしたいことは:マウスをクリックするたびに、クリックした位置に新しい円が作成/描画され、以前に描画された円はすべて移動せずに残ります。

私は次のコードで働いています:

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace multirectangle 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
     SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
    } 
    Bitmap background; 
    Graphics scG; 

    Rectangle rectangleObj; 

    private Point clickCurrent = Point.Empty; 
    private Point clickPrev = Point.Empty; 


    private void Form1_Load(object sender, EventArgs e) 
    { 
     background = new Bitmap(Width, Height); 
     rectangleObj = new Rectangle(10, 10, 30, 30); 
     scG = Graphics.FromImage(background); 
    } 

    private void Form1_MouseDown(object sender, MouseEventArgs e) 
    { 
     clickCurrent = PointToClient(Cursor.Position); 
     clickPrev = clickCurrent; 
     if (clickPrev == Point.Empty) return; 
     rectangleObj.X = clickPrev.X - rectangleObj.Height/2;// +radius; 
     rectangleObj.Y = clickPrev.Y - rectangleObj.Width/2; 
     Refresh(); 
    } 

    protected override void OnPaint(PaintEventArgs pe) 
    { 
     pe.Graphics.DrawImage(Draw(), 0, 0); 

    } 
    public Bitmap Draw() 
    { 
     Graphics scG = Graphics.FromImage(background); 
     Pen myPen = new Pen(System.Drawing.Color.Red, 3); 
     scG.Clear(SystemColors.Control); 
     scG.DrawEllipse(myPen, rectangleObj); 
     return background; 

    } 
} 
} 
+0

プログラムで最後のフレームが何を描画したか分かりません。最も可能性の高い位置のリストを保持し、それらをすべてのフレームごとに描画する必要があります。 –

+0

この 'scG.Clear'は常にビットマップをクリアします。それを削除して報告してください。これはやや複雑なものです。 – TaW

答えて

2

あなたの英語はちょっと混乱していました。私があなたの問題を正しく理解しているのであれば、今は唯一描かれているのは、クリックがあった新しいサークルです。古いものもそのまま残しておきたいですか?その場合、次の2つのオプションがあります。

  1. 描画する前にビットマップをクリアしないでください。 scG.Clear(SystemColors.Control);は、先ほど作成したビットマップを消去します。その行を削除してビットマップをクリアしないと、次回クリックすると最後のビットマップの上に新しい楕円が描画されます。
  2. 新しい図面/ビットマップが毎回必要な場合は、rectangleObjのリストが必要です。クリックするたびに、そのポイントをrectangleObjコレクションに追加します。その後、あなたの描画メソッドでは、コレクションを繰り返し、すべてを描画します。
+0

質問にお答えいただきありがとうございます、私の英語は最高ではありません。私は必要なものを手に入れました。私の必要性、方法2はもっと現実的で、私はそれについて考えました。しかし、私はC#を初めて使ったので、それを適用するコーディング手順はわかりません。例えば、rectangle0bjのリストを作成して100個の円を描きたいのですが。私がする?? – user6425922

+0

クラスでは、長方形のコンテナであるメンバーが必要です。簡単な例がリストです。 Add: 'List rectangleList'次に、あなたのrectangleObjを取得したらマウスの下に、リストに追加します:' rectangleList.Add(rectangleObj) '。ドロースレッドでは、リストを繰り返し、それぞれを描画します。簡単な方法 'for(int i = 0; i Ryan

+0

有益なコメントをありがとう、私は問題を2番目の方法を使用して解決しました。しかし、今私は新しい問題に直面しているコードが遅すぎる実行しています.. http://stackoverflow.com/questionsを見てください/ 37843054 /コードの一部 - make-c-sharp-running-too-it-something-fixab – user6425922

1

私はいくつかのことに気づきます。あなたもそれを保存する前に、古い位置(clickPrev)を上書きしている

clickCurrent = PointToClient(Cursor.Position); 
clickPrev = clickCurrent; 

:まず、Form1_MouseDown()に、あなたはこれを持っています。両方の位置を保持したい場合は、リストのような単純な構造にそれらを配置する必要があります。あなたが新しいポイントを得るとき、ただAdd()それをリストにしてください。次に、あなたのDraw()ルーチンでは、リスト内のすべての要素をループし、それらをすべて描画します。

あなただけの2つの位置をしたい場合は - と2つだけ - ちょうどこのようなあなたの文を入れ替える:

clickPrev = clickCurrent; 
clickCurrent = PointToClient(Cursor.Position); 

をそして、あなたはそれがよりになるだろうが、描画のために別の四角形のオブジェクトを割り当てる必要がありますDraw()ルーチンでこれを処理する感覚。

1

スワップ次の文

clickCurrent = PointToClient(Cursor.Position); 
clickPrev = clickCurrent; 

私はあなたがclickCurrentを初期化した後、あなたはclickPreviousからclickCurrentを割り当てていると思うの位置。それは他の方法である必要があります。

1

削除この

Rectangle rectangleObj; 
Bitmap background; 
Graphics scG; 
Pen myPen; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    rectangleObj = new Rectangle(10, 10, 30, 30); 
    background = new Bitmap(Width, Height); 
    scG = Graphics.FromImage(background); 
    myPen = new Pen(Color.Red, 3); 

    BackgroundImage = background; 
} 

private void Form1_MouseDown(object sender, MouseEventArgs e) 
{ 
    var point = PointToClient(Cursor.Position); 

    rectangleObj.X = point.X - rectangleObj.Height/2; 
    rectangleObj.Y = point.Y - rectangleObj.Width/2; 

    scG.DrawEllipse(myPen, rectangleObj); 
    Refresh(); 
} 

OnPaintDraw方法を試してみてください。同様にclickCurrentclickPrevフィールド。

フォームサイズを変更すると(たとえば、最大化すると)、ビットマップとグラフィックスは同じままなので、この効果が得られます。これを回避するには、すべての以前に描かれたフォームのサイズを変更するたびに、消去されたことをイベントハンドラに

private void Form1_SizeChanged(object sender, EventArgs e) 
{ 
    background = new Bitmap(Width, Height); 
    scG = Graphics.FromImage(background); 
    BackgroundImage = background; 
} 

注意を追加する必要があります。これが望ましくない場合は、描画のために別のアプローチが必要です。もう一つの例を挙げましょう。

+0

お試しいただきありがとうございますが、このコードは私にいくつかの円を描くことができます同じ時間とお互いから一定の距離を持っている。これは便利ですが、残念ながら私がする必要があるものではありません。 – user6425922

+0

@ user6425922 - 私はあなたを理解していません。コードはあなたが望むものとまったく同じです。私はあなたが作品の間にフォームのサイズを変更すると思いますか? –

+0

これはhttp://postimg.org/image/tyepklc1z/ – user6425922

関連する問題