hide and show lines?

payam1363

Member
Joined
Jun 23, 2021
Messages
7
Programming Experience
Beginner
This is main part of my C# code, this is a Windows Forms app.


My code works fine, and it runs the app very well, but I need to change it.

With this app, I can draw some lines in a picturebox, and after I draw the lines, then I can hide lines with press a Key "E" and I can show these lines with press the same key again.

When the lines are hidden, I can left click on the place of a drawn line by mouse, then the app shows that line, and I can hide this line again with a same key "E"

Now my problem is that I can not write a code that: when the mouse moves over the picturebox horizontally, I don't need to click, the app shows that line automatically and when the mouse passed through the picturebox on place of that line, then hide that line again and when mouse arrive to place of next line, app show that other line that mouse in on it and ...

What is your suggest to change the code?

This is my code:
C#:
namespace lines
{
    public partial class Form1 : Form
    {
        private Graphics g;
        private bool drawingMode = true, lineSelected;
        private Pen semiTransPen;
        List<Line> lines = new List<Line>();
        public Form1()
        {
            InitializeComponent();
            var pb = pictureBox1;
            pb.Size = new Size(400, 400);
            pb.Location = new Point(20, 20);
      
            Line line = null;
           

            pb.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left && drawingMode)
                {
                    line.End = e.Location;

                    if (e.Location.Y < 0)
                        line.End = new Point(e.Location.X, 0);
                    else if (e.Location.Y > pb.Size.Height)
                        line.End = new Point(e.Location.X, pb.Size.Height);

                    if (e.Location.X < 0)
                        line.End = new Point(0, e.Location.Y);
                    else if (e.Location.X > pb.Size.Width)
                        line.End = new Point(pb.Size.Width, e.Location.Y);

                    pb.Invalidate();
                }

            };
            pb.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    if (drawingMode)
                        line = new Line (e.Location, e.Location, Pens.Red );
                    else
                    {
                        lineSelected = false;
                        foreach (var a in lines)
                        {
                            if (a.OnLine(e.Location))
                            {
                                a.linePen = semiTransPen = new Pen(Color.FromArgb(75, 0, 0, 255), 5);
                                lineSelected = true;
                            }
                            else
                                a.linePen = semiTransPen = new Pen(Color.FromArgb(1, 0, 0, 255), 5);
                        }
                        pb.Invalidate();
                    }
                }
            };
            pb.MouseUp += (s, e) =>
            {
                if (e.Button == MouseButtons.Left && drawingMode && line.Magnitude() > 1)
                    lines.Add(line);
            };
            pb.Paint += (s, e) =>
            {
                g = pb.CreateGraphics();
            

                if (line != null)
                    e.Graphics.DrawLine(line.linePen, line.Start, line.End);

                foreach (var l in lines)
                    e.Graphics.DrawLine(l.linePen, l.Start, l.End);

            };
            this.KeyPress += (s, e) =>
            {
                if (e.KeyChar == 'e')
                {
                    if (drawingMode)
                    {
                        foreach (var a in lines)
                        {
                            a.linePen = semiTransPen = new Pen(Color.FromArgb(1, 0, 0, 255), 5);
                        }
                    }

                    else
                    {
                        foreach (var a in lines)
                        {
                            a.linePen = Pens.Red;
                        }
                        lineSelected = false;
                    }
                    drawingMode = !drawingMode;
                    pb.Invalidate();
                }
            };
        }



        class Line
        {
            public Line(Point s, Point e, Pen p)
            {
                Start = s;
                End = e;
                linePen = p;
            }
            public Line(string str)
            {
                Point s = new Point(0,0);
                s.X = Int32.Parse(str.Substring(0, str.IndexOf(' ')));
                str = str.Substring(str.IndexOf(' ') + 1);
                s.Y = Int32.Parse(str.Substring(0, str.IndexOf(' ')));
                str = str.Substring(str.IndexOf(' ') + 1);
                Start = s;
                s.X = Int32.Parse(str.Substring(0, str.IndexOf(' ')));
                str = str.Substring(str.IndexOf(' ') + 1);
                s.Y = Int32.Parse(str);
                End = s;
                linePen = Pens.Red;
            }
            public Pen linePen;
            public Point Start { get; set; }
            public Point End { get; set; }

            public bool OnLine(Point p)
            {
                if (p == End || p == Start)
                    return true;

                Point v1 = new Point(p.X - Start.X, p.Y - Start.Y);
                Point v2 = new Point(p.X - End.X, p.Y - End.Y);

                double d1 = v1.X * v2.X + v1.Y * v2.Y;
                double d2 = Math.Sqrt(v1.X * v1.X + v1.Y * v1.Y) * Math.Sqrt(v2.X * v2.X + v2.Y * v2.Y);

                d1 /= d2;

                return (Math.Abs(d1 + 1) < 0.01);
            }

            public int Magnitude()
            {
                Point v1 = new Point(End.X - Start.X, End.Y - Start.Y);
                return v1.X * v1.X + v1.Y * v1.Y;
            }

            public override string ToString()
            {
                return Start.X + " " + Start.Y + " " + End.X + " " + End.Y;
            }
        }
    }
fZySn.gif
 
Last edited by a moderator:
please see again my app !

you see that in my app i drew 5 lines (for example) and then , after i drew that 5 lines , i hide all the lines by press key "E" on keyboard after that , when i click on the location of each line , that line will appear with another color it is very good , but need a change in my code

i want to , (when the mouse move on picturebox) when the mouse crosses the hidden line , show that line under the mouse's location and when the mouse move and crossed that line , hide that line and when it reaches to the next hidden line show that next line and ... continue to do so.. thanks for your help if you have any question i am ready to answer...
 
You have your OnLine() method. In your mouse move event, when the button is not held down and you are not in drawing mode, check the result of OnLine() to determine whether the line should be highlighted as you hover over it.
 
One of the biggest issues that beginners have with solving problems is identifying where the actual problem is. A big part of problem-solving, whether in programming or otherwise, is breaking the problem up into its smallest constituent parts and then addressing each part separately, i.e. divide and conquer. If you do that, you'll often find that large parts of the "problem" are not a problem at all. I suspect that this is such a case.

Immediately, I can see that there are at least two distinct parts to your problem. Hiding and showing lines is completely separate to detecting mouse position relative to lines and should be treated that way. You could write code to hide and show lines based on the states of RadioButtons for the first part, thus having nothing to do with the mouse. In doing that, you would write a dedicated method that would hide and/or show a line. That is now that part done and dusted. You can then work out how to detect when the louse passes over a line completely separately. Once you know how to do that, you simply call your existing method when it happens. There you go: two completely separate problems.

Now, what is your actual problem here?
 
hi
i changed code , now it is very simple than before
please note:


C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace lines
    public partial class Form1 : Form
    {
        List<Line> lines = new List<Line>();
        public Form1()
        {
            InitializeComponent();
            var pb = panel1;
            pb.Size = new Size(400, 400);
            pb.Location = new Point(20, 20);
            Line line = null;

            pb.MouseHover += (s, e) =>
            {
            
                    foreach (var a in lines)
                    {
                        a.linePen = new Pen(Color.FromArgb(100, 0, 255, 0), 5);
                    }
                    pb.Invalidate();

          
            };
            pb.MouseLeave += (s, e) =>
            {
            
                    foreach (var a in lines)
                    {
                        a.linePen = new Pen(Color.FromArgb(0, 0, 0, 0), 5);
                    }
                    pb.Invalidate();

            };
            pb.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    line.End = e.Location;

                    if (e.Location.Y < 0)
                        line.End = new Point(e.Location.X, 0);
                    else if (e.Location.Y > pb.Size.Height)
                        line.End = new Point(e.Location.X, pb.Size.Height);

                    if (e.Location.X < 0)
                        line.End = new Point(0, e.Location.Y);
                    else if (e.Location.X > pb.Size.Width)
                        line.End = new Point(pb.Size.Width, e.Location.Y);

                    pb.Invalidate();
                }

            };
            pb.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                        line = new Line(e.Location, e.Location, Pens.Red);
  
                }
            };
            pb.MouseUp += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                    lines.Add(line);
            };
            pb.Paint += (s, e) =>
            {
                if (line != null)
                    e.Graphics.DrawLine(line.linePen, line.Start, line.End);

                foreach (var l in lines)
                    e.Graphics.DrawLine(l.linePen, l.Start, l.End);
            };
        }
        
        class Line
        {
            public Line(Point s, Point e, Pen p)
            {
                Start = s;
                End = e;
                linePen = p;
            }   
            public Pen linePen;
            public Point Start { get; set; }
            public Point End { get; set; }
        }
    }
}


with this code
only i have a panel (named: panel1) that i can draw some lines in it
after that i drew some lines in panel and then all lines will hide when i move mouse to out of panel , then , when i move mouse in to panel , that lines will appear with another color
, but i need a change in my code
i need to do these actions (show and hide Lines) when mouse hover over each hidden line (and application must show only that one hidden line) ( not when mouse over panel show all lines , likenow)
thanks
 
Last edited:
Back
Top Bottom