2016-08-22 6 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 인식하지 못합니다.

  • 내가 오류가된다 this.shapeFillRectangle(myBrush, rc); 유효하지 않은 파라미터를 갖는다 : 그것은 change() 방법이 라인 말한다.
+0

'change_color'를 호출하기 전에'draw (x, y, w, h)'메서드를 호출하고 있습니까? 그렇게하지 않으려 고 시도하십시오. – CarbineCoder

+0

@CarbineCoder 예, 먼저 변경 방법을 호출 한 후 그릴 수 있습니다. – TheDaJon

+0

그럴 경우 근본 원인을 모르지만 추측 할 때 내 생각은 shape.FillRectange가 작동하지 않습니다. CLASS_NAME – CarbineCoder

답변

1

이제 'drawRectangle'클래스부터 시작해 보겠습니다. 간단한 데이터를 생성하기에 충분한 데이터를 가지고 있으며, 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>(); 

이제 버튼 클릭으로 루프에 추가해 봅시다.

내가 컨트롤을 무효화하는 방법은 내가 그 (것)들을 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 필요; 그것은 완벽하기위한 것이 아닙니다!

다음과 같은 단점이 있습니다. 책임을에게 전파하는 가장 좋은 방법은별로 신경 쓰지 않습니다. 컨트롤에 직사각형을 그려야하는 부담을 덜어 줍니다. 더 복잡한 그리기 코드와 더 많은 컨트롤을 사용하면 각각 복잡한 코드를 배워야합니다. 이것은 좋지 않다.대신 의 책임은 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

:

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포함 false을 정상 색상과 비교하십시오. 트루 컬러 비교를하려면 하나 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

설명 주셔서 대단히 감사합니다. 좋은 대답! ** clickable **을 만들 수있는 방법이 있습니까? 아니면 완전히 다른 질문입니까? – TheDaJon

+0

'MouseClick' 이벤트를 코딩 한 다음 목록을 검색 할 수 있습니다 :'foreach (직사각형에있는 DrawRectangle) if (dr.rect.Contains (e.Location) dosomething..') – TaW

관련 문제