Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
278 views
in Technique[技术] by (71.8m points)

c# - Drawing circles on top of a form

I've got a WinForms app and I want to programatically draw circles on top of certain areas. I'm running into a couple problems and any insight would be appreciated!

1) I've got code for drawing and clearing the circles (see below), but the circles are being drawn behind all my controls. I want them to be drawn as "top-most" in every case. How do I do this?

2) When my app starts up, I'll have some circles that need to be drawn right away. I tried drawing them on the Form Load event to no avail. But as to here (Form graphics not set when form loads) I'm now drawing it on the Paint event. While this works reasonably well (with a bool to make sure it only does it the first time), It seems to have problems with the this.Invalidate(); (as no circles are getting drawn). Is there a better way? Here's my code (parseText runs on a the index change of a comboBox):

private void parseText()
{
    this.Invalidate();
    List<string> lines = new List<string>(richTextBoxRaw.Text.Split(new string[] { Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries));

    foreach (string s in lines)
    {
        switch (s)
        {
            case "<draw1>":
                drawCircle(107, 26, 25);
                break;
            default:
                break;
        }
    }
}

private void drawCircle(int x, int y, int transparency)
{
    if (transparency < 0)
        transparency = 0;
    else if (transparency > 255)
        transparency = 255;

    SolidBrush brush = new SolidBrush(Color.FromArgb(transparency, 255,0,0));
    Graphics graphics = this.CreateGraphics();

    graphics.FillEllipse(brush, new Rectangle(x, y, 25, 25));
    brush.Dispose();
    graphics.Dispose();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    if (starting)
        parseText();

    starting = false;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One of not so complicated and yet working approaches of accomplishing your requirement could be to create custom transparent panel and place it on top of the controls where the red circles will be drawn.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void DrawCircle(int x, int y, int transparency, Graphics graphics)
    {
        if (transparency < 0)
            transparency = 0;
        else if (transparency > 255)
            transparency = 255;

        SolidBrush brush = new SolidBrush(Color.FromArgb(transparency, 255, 0, 0));

        graphics.FillEllipse(brush, new Rectangle(x, y, 25, 25));
        brush.Dispose();
        graphics.Dispose();
    }

    private void TransparentPanel1_Paint(object sender, PaintEventArgs e)
    {
        DrawCircle(10, 10, 255, e.Graphics);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        transparentPanel1.Enabled = false;
        transparentPanel1.Paint += TransparentPanel1_Paint;
        transparentPanel1.BringToFront();
    }
}

public class TransparentPanel : Panel
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
            return cp;
        }
    }
    protected override void OnPaintBackground(PaintEventArgs e)
    {
        //base.OnPaintBackground(e);
    }
}

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...