在WinForms PictureBox中遇到mouseClick事件的问题

时间:2016-02-16 15:33:16

标签: c# winforms

所以,我正在尝试开发一个类似PaintBrush的小应用程序作为大学语言的一部分,它应该是在Windows窗体中制作并使用C#作为语言。到目前为止,我设法编写了我的一个老师的算法来绘制一条线。它应该按照以下方式工作,一旦我点击lineButton,它应该给我一个提示,点击PictureBox中的两个点,一旦两者都被选中,我应该再次点击按钮来绘制线条,不是很优雅或用户友好我知道,但这是我第一次使用UI设计和处理事件的经验,所以我想我会尽可能地保持它,以便更加关注像素着色算法本身。它的工作原理是绘制一条线(有一些小毛刺),但是当我第二次单击它时,它不会再次在PictureBox中选择两个点。这是我的代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CGExercicios
{
    public partial class MyPaint : Form
    {
        Bitmap drawArea;
        Color cor;
        private int drawX;
        private int drawY;
        private Point lineStart;
        private Point lineEnd;
        private bool mousePressed;
        private bool mouseInDrawArea;
        private bool pencilTool;
        private bool lineTool;
        private bool pointsSelected;
        private int numOfClicks; //numero de vezes que a imagem é clicada


        public MyPaint()
        {
            InitializeComponent();
            drawArea = new Bitmap(imagem.Size.Width, imagem.Size.Height);
            pencilTool = false;
            lineTool = false;
            cor = Color.Black; //cor padrao será a cor preta
            numOfClicks = 0;
            pointsSelected = false;
        }

        private void sobreToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void selectColor_Click(object sender, EventArgs e)
        {
            paletaCores.ShowDialog();            
            cor = paletaCores.Color;
        }

        private void imagem_MouseMove(object sender, MouseEventArgs e)
        {

            if (mouseInDrawArea) {

                posX.Text = "X: " + e.X;
                posY.Text = "Y: " + e.Y;

                /* Implementação da ferramenta do lápis */
                if (pencilTool)
                {
                    if (mousePressed)
                    {
                        drawX = e.X;
                        drawY = e.Y;

                        try
                        {
                            drawArea.SetPixel(drawX, drawY, cor);
                            imagem.Image = drawArea;
                        }
                        catch (System.ArgumentOutOfRangeException ecpt)
                        {}
                    }
                } 
            }

        }

        private void imagem_MouseDown(object sender, MouseEventArgs e)
        {
            mousePressed = true;
        }

        private void imagem_MouseUp(object sender, MouseEventArgs e)
        {
            mousePressed = false;
        }

        private void pencilButton_Click(object sender, EventArgs e)
        {
            if (!pencilTool)
                pencilTool = true;
            else
                pencilTool = false;
        }

        private void imagem_MouseLeave(object sender, EventArgs e)
        {
            mouseInDrawArea = false;
            posX.Text = "X:-";
            posY.Text = "Y:-";
        }

        private void imagem_MouseEnter(object sender, EventArgs e)
        {
            mouseInDrawArea = true;
        }

        private void lineButton_Click(object sender, EventArgs e)
        {
            /* Implementação do desenho das retas */
            if (!lineTool)
            {
                lineTool = true;
                numOfClicks = 0;
                if(lineTool) 
                    MessageBox.Show("Clique no ponto inicial e depois no ponto final e pressione o botao novamente");


            }

            else
            {
                if (pointsSelected)
                {
                    drawLine();                    
                }
                else 
                    MessageBox.Show("Pontos não selecionados");
            }



        }

        private void drawLine()
        {

            int dx = lineEnd.X - lineStart.Y;
            int dy = lineEnd.Y - lineStart.Y;
            int steps;
            double x, y; /* Armazenamento real */
            int ix, iy; /* Armazenamento inteiro para plotagem */
            double xincr, yincr;
            x = (double)lineStart.X;
            y = (double)lineStart.Y;

            drawArea.SetPixel(lineStart.X, lineStart.Y, cor);
            steps = Math.Max(Math.Abs(dx), Math.Abs(dy));

            xincr = (double)dx / steps;
            yincr = (double)dy / steps;

            for (int i = 0; i < steps; i++)
            {
                x += xincr;
                ix = (int)Math.Round(x);
                y += yincr;
                iy = (int)Math.Round(y);
                drawArea.SetPixel(ix, iy, cor);
            }
            imagem.Image = drawArea;

            resetLineDraw();

        }

        private void resetLineDraw()
        {

            DebugLabel.Text = "";
            pointsSelected = false;
            lineTool = false;
            numOfClicks = 0;
            imagem.MouseClick -= imagem_MouseClick;


        }

        private void imagem_MouseClick(object sender, MouseEventArgs e)
        {
            /* Captura os pontos inicias e finais se a ferramenta de desenho 
             * de retas esta habilitada */
            if (lineTool && !pointsSelected)
            {
                if (numOfClicks == 1) imagem.MouseClick -= imagem_MouseClick; 
                Point tmp = new Point(e.X, e.Y);

                if (numOfClicks == 0)
                {//Selecionou o primeiro ponto
                    lineStart = tmp;
                    DebugLabel.Text = "Primeiro ponto selecionado";
                }
                else
                {//Selecionou o segundo ponto
                    lineEnd = tmp;
                    pointsSelected=true;
                    DebugLabel.Text = "Segundo ponto selecionado";

                }
                numOfClicks++;
            }              
        }








    }
}

“imagem”是有问题的PictureBox,你可以看到,我已经尝试重置其mouseClick处理程序中使用的变量,但问题仍然存在。有没有办法可能“重置”PictureBox,所以我可以再选择两个点?如果没有,那么我做错了什么导致这个问题呢?

2 个答案:

答案 0 :(得分:0)

据我所见,您正在清除事件imagem.MouseClick并且再也没有将其重新设置。

单击按钮时必须重置事件,例如

imagem.MouseClick += imagem_MouseClick

答案 1 :(得分:0)

出于某种原因,您决定删除imagem图片框的MouseClick处理程序。请见下文,

private void resetLineDraw()
{
    DebugLabel.Text = "";
    pointsSelected = false;
    lineTool = false;
    numOfClicks = 0;

    // this removes the click handler from the picture box.
    // so, if you click on it anymore, nothing will happen.
    //-->  imagem.MouseClick -= imagem_MouseClick;
}

private void imagem_MouseClick(object sender, MouseEventArgs e)
{
    /* Captura os pontos inicias e finais se a ferramenta de desenho 
     * de retas esta habilitada */
    if (lineTool && !pointsSelected)
    {

        // same here
        // --> if (numOfClicks == 1) imagem.MouseClick -= imagem_MouseClick; 
        Point tmp = new Point(e.X, e.Y);

        if (numOfClicks == 0)
        {//Selecionou o primeiro ponto
            lineStart = tmp;
            DebugLabel.Text = "Primeiro ponto selecionado";
        }
        else
        {//Selecionou o segundo ponto
            lineEnd = tmp;
            pointsSelected=true;
            DebugLabel.Text = "Segundo ponto selecionado";

        }
        numOfClicks++;
    }              
}

删除我评论的那些行,它应该可行..至少这似乎是最明显的问题。