2016-08-22 11 views
0

私は内部にグラフィックスを含むC#クラスを作成しました。 これは私がクラスを作成し、矩形を描画する方法です。グラフィック矩形の色を動的に変更します

public Graphics shape; 
public Rectangle rc; 

// constructor 
public CLASS_NAME(Graphics formGraphics) 
{ 
    this.shape = formGraphics; 
} 

public void draw(int x, int y, int w, int h) 
{ 
    SolidBrush myBrush = new SolidBrush(Color.Red); 
    this.rc = new Rectangle(x, y, w, h); 
    this.shape.FillRectangle(myBrush, rc); 

    myBrush.Dispose(); 
} 

はその後、私は色を変更するために、オブジェクトに新しいメソッドを追加したいが、私はこの何も起こらない呼び出すとき:

public void change_color() 
{ 
    SolidBrush myBrush = new SolidBrush(Color.Yellow); 
    this.shapeFillRectangle(myBrush, rc); 
    myBrush.Dispose(); 
} 

私も試してみました:それは完璧に動作しますrc.Fill =が、 VSは有効な方法としてrc.Fillを認識しません。

  • 私がGET ERRORは IS:this.shapeFillRectangle(myBrush, rc);有効でないパラメータがあります。それはchange()方法、この行にと言っています。
+0

'change_color'を呼び出す前に' draw(x、y、w、h) 'メソッドを呼び出していますか?もしそうでなければそれをやってみてください。 – CarbineCoder

+0

@CarbineCoderはい、最初に私はそれを描画し、変更メソッドを呼び出すとonlt – TheDaJon

+0

その場合、根本的な原因はわかりませんが、私の推測はshape.FillRectangeであり、2度目の呼び出しでは機能しません。 CLASS_NAMEの – CarbineCoder

答えて

1

OK、まずは 'drawRectangle'クラスから始めましょう。それは、単純なPenを作成するのに十分なデータを持っていて、Rectangleを保持していて、それが描画されるControlへの参照も保持しています。

私はToStringオーバーライドを追加したので、私たちはそのすべてのプロパティでそれを表示することができ、我々はそれらの矩形のリストが必要ListBox ...

バージョン1

public class DrawRectangle 
{ 
    public Color color { get; set; } 
    public float width { get; set; } 
    public Rectangle rect { get; set; } 
    public Control surface { get; set; } 

    public DrawRectangle(Rectangle r, Color c, float w, Control ct) 
    { 
     color = c; 
     width = w; 
     rect = r; 
     surface = ct; 
    } 

    public override string ToString() 
    { 
     return rect.ToString() + " (" + color.ToString() + 
       " - " + width.ToString("0.00") + ") on " + surface.Name; 
    } 
} 

次を言います:

public List<DrawRectangle> rectangles = new List<DrawRectangle>(); 

ここでボタンをクリックするとループに追加されます:

private void buttonAddLoop_Click(object sender, EventArgs e) 
{ 
    for (int i = 0; i < 10; i++) 
     rectangles.Add(new DrawRectangle(new Rectangle(i * 30, i * 30, 22, 22), 
              Color.Black, 3.5f, drawPanel1)); 
    drawPanel1.Invalidate(); 
} 

コントロールを無効にする方法については、Invalidatingでペイントしてください。 (あなたはControlからForm継承として、同様Formを使用することができます。)このため

を私たちは四角形の一部をペイントする必要がある各コントロールのPaintイベントをコーディングする必要が動作するように。多分別のボタンのクリックで、今、私たちは私たちのDrawRectanglesのいずれかを変更することができます

private void drawPanel1_Paint(object sender, PaintEventArgs e) 
{ 
    foreach (DrawRectangle dr in rectangles) 
    { 
     if (dr.surface == sender) 
     { 
      using (Pen pen = new Pen(dr.color, dr.width)) 
       e.Graphics.DrawRectangle(pen, dr.rect); 
     } 
    } 
} 

:私だけPanel drawPanel1使用

private void buttonChangeButton_Click(object sender, EventArgs e) 
{ 
    rectangles[3].color = Color.Red; 
    rectangles[6].width = 7f; 
    drawPanel1.Invalidate(); 
} 

enter image description here

更新:

上記クラスは「Rectangle」クラスwをカプセル化する方法を簡単に示し始めました。 ould need;それは完璧なものではなかった!

ここには1つの欠陥があります。の責任を広めるための最良の方法については、実際には十分に気にしません。コントロールに四角形を描くという負担がかかり、より複雑な描画コードとより多くのコントロールがある場合は、それぞれ複雑なコードを学習する必要があります。これは良くない。代わりにの責任は、Rectangleクラスにとどまるべきです。コントロールは自分に描画するように指示するだけです。

ここでは、これを行う更新されたクラスがあります。より複雑な図面として、同様に充填された矩形を描画することができるであろう..:

バージョン2

public class DrawRectangle 
{ 
    public Color color { get; set; } 
    public float width { get; set; } 
    public Color fillColor { get; set; } 
    public Rectangle rect { get; set; } 
    public Control surface { get; set; } 

    public DrawRectangle(Rectangle r, Color c, float w, Color fill, Control ct ) 
    { 
     color = c; 
     width = w; 
     fillColor = fill; 
     rect = r; 
     surface = ct; 
    } 

    public DrawRectangle(Rectangle r, Color c, float w, Control ct) 
    : this. DrawRectangle(r, c, w, Color.Empty, ct) {} 

    public override string ToString() 
    { 
     return rect.ToString() + " (" + color.ToString() + 
       " - " + width.ToString("0.00") + ")"; 
    } 

    public void Draw(Graphics g) 
    { 
     if (fillColor != Color.Empty) 
      using (SolidBrush brush = new SolidBrush(fillColor)) 
       g.FillRectangle(brush, rect); 
     if (color != Color.Empty) 
      using (Pen pen = new Pen(color, width)) g.DrawRectangle(pen, rect); 
    } 
} 

それは充填を決定するために第2の色を使用します。 (塗りつぶしの色は、ToStringメソッドには追加しませんでした)。色を特殊色の値Color.Emptyと比較して、描画する必要があるかどうかを判断します。

新しい矩形を作成するループに、塗りつぶし色が追加されるようになりました。そうでない場合は、古いコンストラクタが呼び出され、塗りつぶしの色がColor.Emptyに設定されます。別に

rectangles[2].fillColor = Color.Fuchsia; 

enter image description here

A

private void drawPanel1_Paint(object sender, PaintEventArgs e) 
{ 
    foreach (DrawRectangle dr in rectangles) 
     if (dr.surface == sender) dr.Draw(e.Graphics); 
} 

は、私たちが今書くことができますいくつかの四角形を埋めるために:ここで

Paintイベントが取得する方法は簡単です注意 色比較:それは明らかではありませんが、色Color.Emptyは本当にただ「透明な黒」である一方、(0,0,0,0)、色比較は特別です:NamedColorsだけでなくKnownColorsとして、常にColor.Emptyを含みます偽と通常の色を比較してください。真の色の比較を行うために1はColor「正常」にキャストする必要があります:

bool ok=Color.FromArgb(255,255,255,255) == Color.White; // false 
bool ok=Color.FromArgb(255,255,255 255) == Color.FromArgb(Color.White.ToArgb()); // true 

。したがって Drawコードの比較が安全です。

+0

十分にupvoteできませんでした – CarbineCoder

+0

説明をありがとうございました。素晴らしい答え!それらを**クリック可能な**にする方法がありますか、これはまったく別の質問ですか? – TheDaJon

+0

'MouseClick'イベントをコーディングしてリストを検索することができます:' foreach(DrawRectangle dr in rectangles)if(dr.rect.Contains(e.Location)dosomething..') – TaW

関連する問題