【问题标题】:How to control size and location of circle when I draw it绘制圆时如何控制圆的大小和位置
【发布时间】:2017-03-06 14:37:57
【问题描述】:

我需要帮助解决我不知道如何解决的问题。我有自己的从 PictureBox 扩展的类,我可以正确显示我的矩形,并且可以毫无问题地移动它。

但是当我尝试在矩形周围画一个圆时,我遇到了问题。当用户进行鼠标点击事件时,我想绘制圆圈。它画了一个圆,但在矩形上。我不知道你是否理解我...我将我的代码以及我拥有的结果和我想要的结果放在下面。

我的代码:

OnClick 事件:

//Métodos para mover la unidad
    bool unidadPulsada = false;
    private Point MouseDownLocation;
    protected override void OnMouseDown(MouseEventArgs e)
    {
        unidadPulsada = true;
        base.OnMouseDown(e);
        MouseDownLocation = e.Location;
        DibujarLimites();
    }

设置图片框的方法:

public void Colocar(Control control, Unidad unidad, Point p)
    {
        unidad.Location = p;
        control.Controls.Add(unidad);
    }

绘制方法:

public void DibujarLimites()
    {
        using (Graphics g = CreateGraphics())
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                float[] dashValues = { 5, 2, 15, 4 };
                pen.DashPattern = dashValues;
                DrawCircle(g, pen, 0, 0, 20);
            }
        }
    }

    public void DrawCircle(Graphics g, Pen pen, float centerX, float centerY, float radius)
    {
        g.DrawEllipse(pen, centerX - radius, centerY - radius,
                      radius + radius, radius + radius);
    }

我得到的结果: 左边的矩形是上面画了圆圈的图片框。右边的矩形是没有圆圈的图片框,即原始矩形。

我想要的结果: 围绕矩形绘制的圆圈。

为你编辑:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Forms;
using WHF.Properties;

namespace WHF
{
public class Unidad : PictureBox
{
    //Constructor
    public Unidad(string nombre, string tipo, int movimiento, int ha, int hp, int fuerza, int resistencia, int heridas, int iniciativa, int ataques, int liderazgo, int coste, string rutaImagen)
    {
        tipoUnidad = tipo;
        movimientoUnidad = movimiento;
        nombreUnidad = nombre;
        costeUnidad = coste;
        haUnidad = ha;
        hpUnidad = hp;
        fuerzaUnidad = fuerza;
        resistenciaUnidad = resistencia;
        iniciativaUnidad = iniciativa;
        ataquesUnidad = ataques;
        liderazgoUnidad = liderazgo;
        rutaImagenUnidad = rutaImagen;
    }

    //Propiedades
    public string nombreUnidad { get; set; }
    public string tipoUnidad { get; set; }
    public int movimientoUnidad { get; set; }
    public int costeUnidad { get; set; }
    public int haUnidad { get; set; }
    public int hpUnidad { get; set; }
    public int fuerzaUnidad { get; set; }
    public int resistenciaUnidad { get; set; }
    public int heridasUnidad { get; set; }
    public int iniciativaUnidad { get; set; }
    public int ataquesUnidad { get; set; }
    public int liderazgoUnidad { get; set; }
    public string rutaImagenUnidad { get; set; }

    //Método para dibujar unidad
    public void Colocar(Control control, Unidad unidad, Point p)
    {
        unidad.Location = p;
        control.Controls.Add(unidad);
    }


    //Métodos para mover la unidad
    bool unidadPulsada = false;
    private Point MouseDownLocation;
    protected override void OnMouseDown(MouseEventArgs e)
    {
        unidadPulsada = true;
        base.OnMouseDown(e);
        MouseDownLocation = e.Location;
        //DibujarLimites();

        float x = Location.X + e.X;
        float y = Location.Y + e.Y;

        Graphics graphics = CreateGraphics();

        PointF center = new PointF(x, y);//this.ClientSize.Width / 2F, this.ClientSize.Height / 2F);
        float radius = 100;

        PointF rectOrigin = new PointF(center.X - radius, center.Y - radius);
        RectangleF r = new RectangleF(rectOrigin, new SizeF(radius * 2F, radius * 2F));

        using (Pen p = new Pen(Color.Red, 4))
        {
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
            graphics.DrawEllipse(p, r);
        }
    }
    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (unidadPulsada)
        {
            Left = e.X + Left - MouseDownLocation.X;
            Top = e.Y + Top - MouseDownLocation.Y;
        }
    }
    protected override void OnMouseUp(MouseEventArgs e)
    {
        unidadPulsada = false;
        base.OnMouseDown(e);
        LimpiarLimites();
    }

    //Método para dibujar la zona límite de movimiento de la unidad
    public void DibujarLimites()
    {
        using (Graphics g = CreateGraphics())
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                float[] dashValues = { 5, 2, 15, 4 };
                pen.DashPattern = dashValues;
                DrawCircle(g, pen, 0, 0, 20);
            }
        }
    }

    //Método para limpiar el dibujo de la zona límite
    public void LimpiarLimites()
    {

    }

    public void DrawCircle(Graphics g, Pen pen, float centerX, float centerY, float radius)
    {
        g.DrawEllipse(pen, centerX - radius, centerY - radius, radius + radius, radius + radius);
    }

    public void FillCircle(Graphics g, Brush brush, float centerX, float centerY, float radius)
    {
        g.FillEllipse(brush, centerX - radius, centerY - radius, radius + radius, radius + radius);
    }
}
}

【问题讨论】:

  • this
  • 你想在PicureBox 上还是在它周围画一个圆圈?
  • 在它周围,它不随图片框移动。我想让它看到pictureBox的移动极限区域。
  • 所以如果你想在PictureBox周围看到它,那么你需要在它的父表面上绘制而不是在控件上绘制。
  • 是的,但是当用户在图片框上进行 mouseclickevent 时我需要绘制它,并且该事件在我的 Unidad.cs 类上。 Unidad 扩展了图片框。

标签: c# class draw picturebox geometry


【解决方案1】:

好吧,这里举个例子,我尝试过和你一样的方式应用,我已经创建了自己的图片框,

class MyPBox : PictureBox
    {
    public MyPBox()
    {
        this.BackColor = Color.Red; // for see better
        this.Location = new Point(50, 50); // set location at form

    }
    protected override void OnPaint(PaintEventArgs pe)
    {
        if (this.Parent != null)
        {
            this.Parent.Paint += Parent_Paint; // picturebox's paint means it added to parent so we need to trigger parent's paint event
        }
        base.OnPaint(pe);

    }
    bool clickPerformed = false; // to catch control has mouse down
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        clickPerformed = true; // set mouse down
        Control tempSender =  this.Parent; // get sender
        tempSender.Invalidate(); // invalidate to trigger paint event

    }

    private void Parent_Paint(object sender, PaintEventArgs e)
    {
        if (clickPerformed)
        {
            using (Graphics g = e.Graphics)
            {
                using (Pen pen = new Pen(Color.Black, 2))
                {
                    float locationX = this.Location.X + this.Size.Width / 2;
                    float locationY = this.Location.Y + this.Size.Height / 2;
                    float radius = (this.Size.Height + this.Size.Width) / 2;

                    float[] dashValues = { 5, 2, 15, 4 };
                    pen.DashPattern = dashValues;
                    DrawCircle(g, pen, locationX
                        , locationY
                        , radius); // draw circle 
                    clickPerformed = false; // process done so set it to false
                }
            }
        }
        base.OnPaint(e);

    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        this.Parent.Invalidate(); // mouse up circle should be erased, so invalidate again to trigger paint, but this time clickPerformed is false
        // so it won't draw circle again
        base.OnMouseDown(e);
    }
    public void DrawCircle(Graphics g, Pen pen, float centerX, float centerY, float radius)
    {
        g.DrawEllipse(pen, centerX - radius, centerY - radius, radius + radius, radius + radius);
    }

}

结果(我正在点击图片框 btw :));

希望有帮助,

【讨论】:

    【解决方案2】:

    0,0 是图片框的左上角。你想做的是

    public void DibujarLimites()
    {
        using (Graphics g = CreateGraphics())
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                float[] dashValues = { 5, 2, 15, 4 };
                pen.DashPattern = dashValues;
                DrawCircle(g, pen, this.height/2, this.width/2, 20);
            }
        }
    }
    

    【讨论】:

    • 不,我在编辑过的问题上解释得更好。当用户进行 mouseclickevent 并且此事件位于 myUnidad.cs 类上时,我想画一个圆圈,该类扩展了图片框。所以我不能用你的答案来解决,因为它把圆圈画到了图片框里,不是吗?
    【解决方案3】:

    把它放在你的图片框的onclick事件中,你应该没问题

    float x = Location.X + e.X;
    float y = Location.Y + e.Y;
    
    Form form = (Form)this.FindForm();
    Graphics graphics = form.CreateGraphics();
    
    PointF center = new PointF(x, y);//this.ClientSize.Width / 2F, this.ClientSize.Height / 2F);
    float radius = 100;
    
    PointF rectOrigin = new PointF(center.X - radius, center.Y - radius);
    RectangleF r = new RectangleF(rectOrigin, new SizeF(radius * 2F, radius * 2F));
    
    using (Pen p = new Pen(Color.Blue, 4))
    {
         p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
         graphics.DrawEllipse(p, r);
    }
    

    【讨论】:

    • 不,我在编辑后的问题上解释得更好。当用户进行 mouseclickevent 并且此事件位于 myUnidad.cs 类上时,我想画一个圆圈,该类扩展了图片框。所以我不能用你的答案来解决,因为它把圆圈画进了图片框,不是吗?
    • 我试了一下,但什么都看不到。我的意思是,我认为它没有画出圆圈,或者我看不到它被画出来。你能帮帮我吗?
    • 我现在可以看到圆圈了。它是图片框右下角一个完整圆圈的一小部分。它在图片框上,而不是在外面。
    • 你能发布你实现我的代码的方法吗?
    • 是的,你有这个问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多