draggable line(rectangle) in c #???

Hi,

I am trying to find a way to draw draggable vertical lines on top of line chart(zedgraph).
I have been looking at this for a while to figure out how I should do this.
Since I don't know how to do this, I came up to this so far.
1) draw vertical lines and draw invisiable rectangle around that line
2) Set up mouse even on that rectangle and when mouse down happens  a while mouse comes in that box, redraw line and box at the new point of mouse moved to.

Would this work ??

I need your help to with what I can use, panel, picturebox??
A little startup sample code or example in c# will be greatly appreciated.
Thanks much
dkim18Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Babycorn-StarfishCommented:
Sounds like you're on the right track.

I can't find the pen drive with my code on but from what i remember i did the following:

create a class with two points in it (start and end) and the rectangle for the hit testing, expose properties or methods to access these fields

have a generic list object that stores this class

on mouse down event create a Rectangle based on the current mouse coordinates with a width/height of 1.

iterate over the list and see whether any of the items.Rectangle property contains the rectangle you just created, if it does you have a hit.

If you have a hit you need to store the mouse position and in the mouse up event store the new position, then using these two points you can determine which way to move the line

0
Babycorn-StarfishCommented:
I found my code, i chopped out all the irrelevant stuff.

I have a form with a panel on it called panel3 (i have others which i'll omit here)

In my code i'm concerned with Rectangles only, you can drag them about etc, a bit of modification should make it wokr for lines after all a line is just a rectangle with a width of 1 or a height of 1.

Ask any questions you like about the code :)
namespace KeyboardLayoutTool
{
    public partial class Form1 : Form
    {
        private List<Rectangle> rects = new List<Rectangle>();
        private int currIdx = -1; 
        private Point oldPoint;
        private Point newPoint;
        private Boolean hit = false;
        private Boolean mouseDown = false;  
 
        public Form1()
        {
            InitializeComponent();
            rects.Add(new Rectangle(1, 1, 10, 10));
            rects.Add(new Rectangle(20, 11, 10, 10));
            rects.Add(new Rectangle(40, 21, 10, 10));
            rects.Add(new Rectangle(60, 31, 10, 10));
            rects.Add(new Rectangle(80, 41, 10, 10));
        } 
 
        private void panel3_Paint(object sender, PaintEventArgs e)
        {
            foreach (Rectangle r in rects)
            {
                if (r != Rectangle.Empty)
                {
                    e.Graphics.FillRectangle(Brushes.Red, r);
                }
            }
        } 
        private void panel3_MouseDown(object sender, MouseEventArgs e)
        {
            currIdx = -1;
            for (int idx = 0; idx < rects.Count; idx++)
            {
                if (rects[idx].Contains(e.Location))
                {
                    if (e.Button == MouseButtons.Left)
                    {
                        oldPoint = e.Location;
                        currIdx = idx;
                        mouseDown = true;
                        hit = true;
                    }
                    return;
                }
            }
            hit = false;
            return;
        }
 
        private void panel3_MouseUp(object sender, MouseEventArgs e)
        {
            mouseDown = false;
            hit = false;
            Invalidate(true);
            Update();
 
        }
 
        private Point GetDifference(Point end, Point start)
        {
            return new Point(end.X - start.X, end.Y - start.Y);
        }
 
        private void panel3_MouseMove(object sender, MouseEventArgs e)
        {
            //need to adjust so that the rectangle is in equivalent position
            if (mouseDown && hit)
            {
                newPoint = e.Location;
                Point diff = GetDifference(newPoint, oldPoint);
                Rectangle curr = rects[currIdx];
                curr.X += diff.X;
                curr.Y += diff.Y;
                //ShowCurrRectCoordinates(curr.X, curr.X);
                rects[currIdx] = curr;
                //invalidate and repaint
                Invalidate(true);
                Update();
                oldPoint = newPoint;
            }
        }
 
        private void ShowCurrRectCoordinates(int x, int y)
        {
            this.textBox1.Text = "x: " + x + ", y: " + y;
        }
 
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
dkim18Author Commented:
Babycorn-Starfish,

Thanks so much for answering and getting the code for me.
I will try out your code and let you know if I can figure out from your code.
Again thanks much.

0
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

Babycorn-StarfishCommented:
No probs, hope you can adapt it to what you want.  Post here if you've any questions about adapting it to your needs :)
0
dkim18Author Commented:
Babycorn-Starfish,

I ran your code and worked fine.
Thanks so much.

Can I ask a few more questions please?
I know these are things I need to think about myself but can use help!!

1) I want that rectangle(line, width of 1) to move from left to right direction.
when I move it downward, I see length of line gets reduced, meaning it is moving downward. How can I stop that??

2) Two lines come across when I move them, how can I stop two lines to pass each other??

3) I want two lines to stay on the graph( panel or rectangle). Just stay inside of x axis..

Maybe I should create a thread..
Thanks again.
0
Babycorn-StarfishCommented:
Hi again,

post the code that you have so far and i'll try and modify it for you, i'll comment it so you'll understand the changes.

0
dkim18Author Commented:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DragLineTest
{
  public partial class Form1 : Form
  {
    private List<Rectangle> rects = new List<Rectangle>();
    private int currIdx = -1;
    private Point oldPoint;
    private Point newPoint;
    private Boolean hit = false;
    private Boolean mouseDown = false;

    public Form1()
    {
      InitializeComponent();
      Rectangle rect1 = new Rectangle(1, 1, 190, 100);
      Rectangle leftBar = new Rectangle(21, 1, 1, 100);
      Rectangle rightBar = new Rectangle(170, 1, 1,100);
      rects.Add(rect1);
      rects.Add(leftBar);
      rects.Add(rightBar);
   
    }
    private void panel1_Paint(object sender, PaintEventArgs e)
    {
      e.Graphics.DrawRectangle(Pens.Black,rects[0]);
      e.Graphics.FillRectangle(Brushes.Red, rects[1]);
      e.Graphics.FillRectangle(Brushes.Red, rects[2]);
   
    }
    private void panel1_MouseDown(object sender, MouseEventArgs e)
    {
      currIdx = -1;
      for (int idx = 1; idx < rects.Count; idx++)
      {
        if (rects[idx].Contains(e.Location))
        {
          if (e.Button == MouseButtons.Left)
          {
            oldPoint = e.Location;
            currIdx = idx;
            mouseDown = true;
            hit = true;
          }
          return;
        }
      }
        hit = false;
        return;
    }
    private void panel1_MouseUp(object sender, MouseEventArgs e)
    {
      mouseDown = false;
      hit = false;
      Invalidate();
      Update();
    }
    private Point GetDifference(Point end, Point start)
    {
      return new Point(end.X - start.X, end.Y - start.Y);
    }
    private void panel1_MouseMove(object sender, MouseEventArgs e)
    {
      if (mouseDown && hit)
      {      
            newPoint = e.Location;
            Point diff = GetDifference(newPoint, oldPoint);
            Rectangle currentRect = rects[currIdx];
            currentRect.X += diff.X;
            currentRect.Y += diff.Y;
            ShowCurrectRectCoordinates(currentRect.X, currentRect.Y);
            rects[currIdx] = currentRect;
            Invalidate(true);
            Update();
            oldPoint = newPoint;      
      }
    }
    private void ShowCurrectRectCoordinates(int x, int y)
    {
      this.textBox1.Text = "x: " + x + " y: " + y;
   

    }
  }
}
0
Babycorn-StarfishCommented:
Actually, this is more reliable, BUT (perhaps it's because i'm using a laptop's touch pad instead of a 'real' mouse) i found it hard to move the lines because there always seemed to be an element of up/down motion which cancels the overall line movement. Let me know how it works for you. Incidentally the IntersectsWith method i used earlier is a no go, doesn't always work :(

private const int LEFT = 0;
        private const int RIGHT = 1;

        private void panel3_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown && hit)
            {
                newPoint = e.Location;
                Point diff = GetDifference(newPoint, oldPoint);
                Rectangle currentRect = rects[currIdx];
                currentRect.X += diff.X;
                currentRect.Y += diff.Y;

                switch (currIdx)
                {
                    case LEFT://left most line
                        {
                            if (currentRect.X >= rects[RIGHT].X)
                            {
                                return;
                            }
                            else if(currentRect.X <= rect1.X)
                            {
                                return;
                            }    
                            break;
                        }
                    case RIGHT://right most line
                        {
                            if (currentRect.X <= rects[LEFT].X)
                            {
                                return;
                            }
                            else if (currentRect.X >= rect1.X + rect1.Width)
                            {
                                return;
                            }
                            break;
                        }
                    default:
                        {
                            break;
                        }
                }

                if (currentRect.Y <= rect1.Y)
                {
                    return;
                }
                else if (currentRect.Y + currentRect.Height >= rect1.Y + rect1.Height)
                {
                    return;
                }

                ShowCurrectRectCoordinates(currentRect.X, currentRect.Y);
                rects[currIdx] = currentRect;
                Invalidate(true);
                Update();
                oldPoint = newPoint;
            }
        }
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.