【问题标题】:Drawing circles on top of a form在表格顶部绘制圆圈
【发布时间】:2016-10-22 15:19:14
【问题描述】:

我有一个 WinForms 应用程序,我想以编程方式在某些区域顶部绘制圆圈。我遇到了几个问题,任何见解都将不胜感激!

1) 我有绘制和清除圆圈的代码(见下文),但圆圈是在我的所有控件后面绘制的。我希望它们在每种情况下都被绘制为“最重要的”。我该怎么做?

2) 当我的应用程序启动时,我将需要立即绘制一些圆圈。我尝试在 Form Load 事件上绘制它们无济于事。但至于这里 (Form graphics not set when form loads) 我现在在 Paint 事件中绘制它。虽然这工作得相当好(使用 bool 确保它只在第一次这样做),但 this.Invalidate(); 似乎有问题(因为没有画出圆圈)。有没有更好的办法?这是我的代码(parseText 在组合框的索引更改上运行):

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;
}

【问题讨论】:

  • 你需要了解一些基础知识。 1.您需要从Paint Event(而不是从表单加载)调用您的代码,以便在窗口需要屏幕刷新时始终正确更新。 2. 请记住,表单将具有控件,这些控件具有自己的绘制例程。这将清除您的墨水。您可以注册控件的绘制事件并在控件上绘图。现在您还可以创建一个覆盖表单上所有控件的用户控件(Z-Order 为零)并在那里绘制您的圆圈,但是您需要逻辑将您的事件传递给您的用户控件下方的控件。没有简单的解决方案。

标签: c# winforms brush


【解决方案1】:

实现您的要求的一种不太复杂但可行的方法是创建自定义透明面板并将其放置在将绘制红色圆圈的控件顶部。

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);
    }
}

【讨论】:

  • 所以我已经实现了你的建议,它似乎工作得很好,除了我有一个选项卡控件 - 选项卡控件似乎覆盖了 transparentPanel 的“BringToFront”(似乎没有成为 tabControl 的绘制事件,我可以将 transparentPanel.BringToFront(); 放入)
  • 您可以订阅TabControl.TabPages[0].Paint并调用transparePanel.Refresh();
猜你喜欢
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 2014-04-11
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多