Home > Back-end >  C# Windows Forms - MouseDownEvent with PictureBox
C# Windows Forms - MouseDownEvent with PictureBox

Time:06-29

I want to build an application to visualize searching algorithms (such as DFS, BFS) using C#.
I am using .cs files, and not xaml or xml.
So I made a matrix of 50X50 pictureboxes, each one has its own matrix indexes, and it's location on the gui window. enter image description here

So this is my map so far. What I'm trying to achieve is that every time I encounter MouseDownEvent, I want the specific picturebox to be chosen, and change it's color.
But I can't figure out how to do it.
I have my initBoard code:

private void initBoard()
{
    m_VisualizerPictureBox = new UpgradedPictureBox[m_BoardHeight, m_BoardWidth];
    int left = 0, top = (Top / 2 - m_BoardHeight);
    for (int i = 0; i < m_BoardHeight; i  )
    {
       left = Left / 2 - (m_BoardWidth - 1);
       for(int j = 0; j < m_BoardWidth; j  )
       {
           m_VisualizerPictureBox[i, j] = new UpgradedPictureBox(new Point(i, j))
                                              {
                                                  Size = m_ButtonSize,
                                                  Top = (i * m_ButtonSize.Width),
                                                  Left = (j * m_ButtonSize.Width),
                                                  Location = new Point(left, top),
                                                  BackColor = Color.Aqua,
                                                  BorderStyle = BorderStyle.FixedSingle
                                              };
           left  = m_ButtonSize.Width;
           m_VisualizerPictureBox[i, j].m_PositionOnBoard = new Point(i, j);
           int x = ((i   1) * top)   left;
           int y = ((j   1) * left)   top;
           Point XYPoint = new Point(x,y);
           m_VisualizerPictureBox[i, j].m_XYPosition = XYPoint;
           Controls.Add(m_VisualizerPictureBox[i, j]);
           int copyOfI = i, copyOfJ = j;
           m_VisualizerRectangles[i, j].Click  = (sender, e) => buttonClicked(copyOfI, copyOfJ);
               m_VisualizerRectangles[i, j].MouseDown  = (MouseDownEvent);
               m_VisualizerRectangles[i, j].MouseUp  = (MouseUpEvent);
               m_VisualizerRectangles[i, j].MouseEnter  = (mouseEnterEvent);
       }

       top  = m_ButtonSize.Height;
    }
}

I don't want the user to press every single picturebox in a different press, I want the user to press his mouse, keep it down, and it will keep marking the pictureboxes as I need.

So I thought the next code should do it:

private void buttonClicked(int i_Row, int i_Col)
        {
            UpgradedPictureBox buttonClicked = m_VisualizerRectangles[i_Row, i_Col];
            if(m_VisualizerRectangles[i_Row,i_Col].BackColor == buttonClicked.m_DefaultBackColor)
            {
                m_VisualizerRectangles[i_Row, i_Col].BackColor = Color.Black;
            }
            else
            {
                m_VisualizerRectangles[i_Row, i_Col].BackColor = buttonClicked.m_DefaultBackColor;
            }
        }

        private void MouseDownEvent(object sender, EventArgs e)
        {
            m_MouseIsDown = true;
            m_MouseIsUp = false;
        }

        private void MouseUpEvent(object sender, EventArgs e)
        {
            m_MouseIsUp = true;
            m_MouseIsDown = false;
        }

        private void mouseEnterEvent(object sender, EventArgs e)
        {
            if(m_MouseIsDown)
            {
                UpgradedPictureBox pictureClicked = sender as UpgradedPictureBox;
                int row = pictureClicked.m_PositionOnBoard.X;
                int col = pictureClicked.m_PositionOnBoard.Y;
                if(m_VisualizerRectangles[row, col].BackColor == pictureClicked.m_DefaultBackColor)
                {
                    m_VisualizerRectangles[row, col].BackColor = Color.Black;
                }
                else
                {
                    m_VisualizerRectangles[row, col].BackColor = pictureClicked.m_DefaultBackColor;
                }
            }
        }

However, the if statement at m_MouseIsDown is not letting me mark the pictureboxes when the mouse is pressed. When I cancel this if statement, it lets me mark exactly how I want, but without my mouse being pressed. What am I missing here?

CodePudding user response:

I believe you're seeing this behavior because PictureBox tries to multiple squares colored by mouse

I was able to achieve this outcome by setting the Capture property to false in the UpgradedPictureBox method that overrides the MouseDown event.

public class UpgradedPictureBox : PictureBox
{
    protected override void onm ouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        BackColor = Color.Fuchsia;
        Capture = false;
    }
    protected override void onm ouseEnter(EventArgs e)
    {
        base.OnMouseEnter(e);
        if (MouseButtons == MouseButtons.Left)
        {
            BackColor = Color.Fuchsia;
        }
    }
}

So maybe give this a try and test whether it works on your side.

  • Related