【问题标题】:C# draw ellipse on mouse click on FormC# 在窗体上单击鼠标绘制椭圆
【发布时间】:2017-04-28 16:15:32
【问题描述】:

我很擅长用 C# 绘图 我想在鼠标点击时在 Form 上绘制椭圆。我写了一个代码,但它不想在鼠标点击时绘图。这是我的代码:

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
{   public Form1()
    {
        InitializeComponent();
    }
    Pen p = new Pen(Color.Red, 3);
    SolidBrush b = new SolidBrush(Color.Red);
    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        Graphics g = CreateGraphics();

        if (radioButton1.Checked)
        {
            p.Color = Color.Red;
            b.Color = Color.Red;

            }
        if (radioButton2.Checked)
        {
            p.Color = Color.Yellow;
            b.Color = Color.Yellow;

            }
        if (radioButton3.Checked)
        {
            p.Color = Color.Blue;
            b.Color = Color.Blue;

            }
        if (checkBox1.Checked)
            g.FillEllipse(b, e.X, e.Y, 50, 50);

        else
            g.DrawEllipse(p, e.X, e.Y, 50, 50);
            g.Dispose();
    }
}
}

【问题讨论】:

  • 您不应使用CreateGraphics 劫持控件的绘图表面。当窗体重新绘制时,您以这种方式绘制的任何内容都将消失。此外,您没有处理您的 PenSolidBrush 资源,因此您有 GDI 资源泄漏。

标签: c# drawing ellipse


【解决方案1】:

您不应使用CreateGraphics 劫持控件的绘图表面。当窗体重新绘制时,您以这种方式绘制的任何内容都将消失。此外,您没有处理您的PenSolidBrush,因此您有 GDI 资源泄漏。

相反,创建一个要绘制的椭圆列表,然后在 OnPaint 覆盖形式中绘制它们。

类似这样的:

首先创建一个类来表示你的形状:

public class Ellipse
{
    public Color Color { get; set; }
    public Point Location { get; set; }
    public Size Size { get; set; }
    public bool Filled { get; set; }
}

然后,当鼠标在表单上单击时,创建一个新的形状实例并将其添加到列表中。

public partial class Form1 : Form
{
    //A list to hold all the ellipses to be drawn
    private List<Ellipse> ellipses = new List<Ellipse>();

    public Form1()
    {
        InitializeComponent();
    }

    protected override void OnMouseClick(MouseEventArgs e)
    {
        //When the form is clicked, create a new ellipse and add it to the list.
        ellipses.Add(new Ellipse
        {
            Color = radioButton1.Checked ? Color.Red : (radioButton2.Checked ? Color.Yellow : Color.Blue),
            Location = e.Location,
            Size = new Size(50, 50),
            Filled = checkBox1.Checked
        });

        //Tell the form to redraw itself
        this.Invalidate();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        //Redraw each ellipse in the list.
        foreach (var ellipse in ellipses)
        {
            if (ellipse.Filled)
            {
                //Use a using block to make sure the resource is disposed
                using (var b = new SolidBrush(ellipse.Color))
                {
                    e.Graphics.FillEllipse(b, new Rectangle(ellipse.Location, ellipse.Size));
                }
            }
            else
            {
                //Use a using block to make sure the resource is disposed
                using (var p = new Pen(ellipse.Color))
                {
                    e.Graphics.DrawEllipse(p, new Rectangle(ellipse.Location, ellipse.Size));                        
                }
            }
        }
    }
}

【讨论】:

  • 或者将您的SolidBrushPen 创建为实例变量并重用它们。
  • @Chris Dunaway:我对绘制用户(自定义)控件还很陌生;但我已经取得了一些成就。您能否为您的答案提供更多信息?比如:为什么“你不应该使用 CreateGraphics 来劫持控件的绘图表面。当窗体重新绘制时,你以这种方式绘制的任何东西都会消失”和一个详细的解决方案,以便学习的人可以理解它应该是什么完毕?提前致谢
【解决方案2】:

问题可能不是绘图功能。

我简化了它来测试它,它对我有用:

    Pen p = new Pen(Color.Red, 3);
    SolidBrush b = new SolidBrush(Color.Red);

    private void Form1_MouseClick(object sender, MouseEventArgs e)
    {
        Graphics g = this.CreateGraphics();

        p.Color = Color.Blue;
        b.Color = Color.Blue;
        g.FillEllipse(b, e.X, e.Y, 50, 50);
        g.DrawEllipse(p, e.X, e.Y, 50, 50);
        g.Dispose();
    }

【讨论】:

  • CreateGraphics 是临时的。不要使用它。使用容器的绘制事件。
  • 有趣的是,这个答案是唯一一个真正展示了一些东西的答案。克里斯的回答根本没有做任何事情,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多