简体   繁体   English

C#在面板中绘制圆

[英]C# Drawing circles in a panel

i am doing a program on the math "Problem of Apollonius". 我正在做一个数学上的程序“ Apollonius问题”。 But first my program needs to be able to allow the users to draw three circles on a panel, the circles can differ from size and position. 但是首先,我的程序需要能够允许用户在面板上绘制三个圆圈,圆圈的大小和位置可以不同。

I cant figure out how to allow the users to draw their on size circle on the panel. 我想不通如何允许用户在面板上绘制尺寸圆圈。 Any help would be greatly appreciated. 任何帮助将不胜感激。

Here is a simple demonstration for Windows Forms. 这是Windows窗体的简单演示。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

// Definition for our ellipse object.
class Ellipse
{
    public int PenWidth;
    public Color Color;
    public Rectangle Rectangle;

    // Paint ourselves with the specified Graphics object
    public void Draw(Graphics graphics)
    {
        using (Pen pen = new Pen(Color, PenWidth))
            graphics.DrawEllipse(pen, Rectangle);
    }
}

class Form1 : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public Form1()
    {
        // Remove "flickering" from the repainting.
        SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
    }

    // Store all created ellipses so they can be rendered during the Paint event.
    List<Ellipse> ellipses = new List<Ellipse>();

    // Definition of an Ellipse under construction
    class EllipseConstruction
    {
        public Point Origin;
        public Ellipse Ellipse;
    }

    // Storage for ellipse under construction.
    EllipseConstruction ellipseConstruction;

    // Random number generator Ellipse creation.
    private Random Rand = new Random();

    // These are the possible ellipse colors
    static readonly Color[] EllipseColors =
    {
        Color.Black,
        Color.White,
        Color.Red,
        Color.Green,
        Color.Blue,
        Color.Yellow,
        Color.Magenta,
        Color.Cyan,
    };

    protected override void OnMouseDown(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            // Capture mouse until button up.
            Capture = true;

            // Create a new Ellipse object and record the [X, Y] origin of this click
            ellipseConstruction = new EllipseConstruction
            {
                Origin = e.Location,
                Ellipse = new Ellipse { Color = EllipseColors[Rand.Next(EllipseColors.Length)], PenWidth = Rand.Next(1, 6) },
            };
        }

        base.OnMouseDown(e);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        // If the mouse is captured, the user is creating a new Ellipse so we update its rectangle with the mouse coordinates
        if (Capture)
            UpdateEllipseUnderConstruction(e.Location);

        base.OnMouseMove(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (Capture && e.Button == MouseButtons.Left)
        {
            // If the mouse is captured and it's the Left button being released, the user is
            //   done creating a new Ellipse.

            // Stop capturing the mouse.
            Capture = false;

            // Final update of the Ellipse under construction
            UpdateEllipseUnderConstruction(e.Location);

            // Add the new Ellipse to our list unless its width or height are zero which would result in a non-visible ellipse
            if (ellipseConstruction.Ellipse.Rectangle.Width > 0 && ellipseConstruction.Ellipse.Rectangle.Height > 0)
                ellipses.Add(ellipseConstruction.Ellipse);

            // Since we are done constructing a new Ellipse, we don't need the construction object
            ellipseConstruction = null;
        }

        base.OnMouseUp(e);
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
        // Allow Ellipse creation to be cancelled with the Escape key
        if (Capture && e.KeyData == Keys.Escape)
        {
            Capture = false; // End mouse capture
            ellipseConstruction = null; // Remove construction ellipse
            Invalidate(); // Notify operating system that we need to be repainted.
        }

        base.OnKeyDown(e);
    }

    private void UpdateEllipseUnderConstruction(Point point)
    {
        // Calculate new ellipse rectangle based on ellipseConstruction.Origin and point.

        Point origin = ellipseConstruction.Origin;

        int xRadius = Math.Abs(origin.X - point.X);
        int yRadius = Math.Abs(origin.Y - point.Y);

        // Make X and Y radii the same for a true circle unless the Shift key is held down
        if ((ModifierKeys & Keys.Shift) == 0)
            xRadius = yRadius = Math.Max(xRadius, yRadius);

        ellipseConstruction.Ellipse.Rectangle = new Rectangle(origin.X - xRadius, origin.Y - yRadius, xRadius * 2, yRadius * 2);

        Invalidate(); // Notify operating system that we need to be repainted.
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        // Paint the background since we specified ControlStyles.AllPaintingInWmPaint and ControlStyles.Opaque.
        e.Graphics.Clear(Color.SlateGray);

        // Paint the ellipses we have stored.
        foreach (Ellipse ellipse in ellipses)
            ellipse.Draw(e.Graphics);

        // If the user is creating a new ellipse paint it.
        if (ellipseConstruction != null)
            ellipseConstruction.Ellipse.Draw(e.Graphics);

        base.OnPaint(e);
    }
}
  1. In the MouseDown event, capture the location of the center (or top corner of bounding box, according to preference) of the circle, and the fact that a circle is being drawn. 在MouseDown事件中,捕获圆的中心(或根据喜好,边界框的上角)的位置,以及绘制圆的事实。
  2. In the MouseMove event, if a circle is being drawn, then draw the circle, using the current mouse location as a point on the edge of the circle (or opposite corner of bounding box, according to preference) 在MouseMove事件中,如果正在绘制一个圆,则使用当前鼠标位置作为圆边缘(或根据喜好,位于边界框的对角)上的一个点来绘制该圆
  3. In the MouseUp event, capture the radius of the circle and the fact that it is no longer being drawn. 在MouseUp事件中,捕获圆的半径以及不再绘制圆的事实。 Store the newly created circle in the circle collection, and render it to the screen. 将新创建的圆存储在circle集合中,并将其渲染到屏幕上。

In some older technologies, you would have to erase and redraw the circle in the MouseMove event of step 2. If you are using WPF, or something similarly advanced, you can just create a circle object and add it to a canvas in step 1, and then manipulate its properties in step 2. The WPF engine will take care of erasing the circle from the old location and drawing it in the new location. 在某些较旧的技术中,您将必须在步骤2的MouseMove事件中擦除并重画该圆。如果您使用的是WPF或类似的高级工具,则​​只需在步骤1中创建一个圆对象并将其添加到画布中即可。然后在步骤2中操纵其属性。WPF引擎将负责从旧位置擦除圆并在新位置绘制圆。

You can draw on all winforms control using Graphics. 您可以使用“图形”来绘制所有winforms控件。 For example: 例如:

private void button1_Click(object sender, EventArgs e)
{
  System.Drawing.Graphics g = System.Drawing.Graphics.FromHwnd(panel1.Handle);
  g.DrawEllipse(Pens.Green, panel1.ClientRectangle);
}

But in this case your painting will disappear if the form is redrawn. 但是在这种情况下,如果重新绘制表格,您的绘画将消失。 So you need to do it in the OnPaint method. 因此,您需要在OnPaint方法中执行此操作。 If want to force form redrawing you can simply call the Invalidate method of your form: 如果要强制重新绘制表单,则只需调用表单的Invalidate方法即可:

this.Invalidate();

Use Graphics.DrawEllipse method: 使用Graphics.DrawEllipse方法:

  // Create pen.
    Pen blackPen = new Pen(Color.Black, 3);
    // Create rectangle for circle.
    Rectangle rect = new Rectangle(0, 0, 100, 100);
    // Draw circle.
    e.Graphics.DrawEllipse(blackPen, rect);

Obtain a Graphics object from your surface on which you want to draw. 从要在其上绘制表面的图形对象中获取一个Graphics对象。

You can draw on a panel using Graphics class in the Paint event handler of the Panel. 您可以在面板的Paint事件处理程序中使用Graphics类在面板上绘制

Have a look at this article on CodeProject and there are a lot on the internet. 看看CodeProject上的这篇文章 ,互联网上有很多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM