Solved

draggable line(rectangle) in c #???

Posted on 2007-11-20
8
2,047 Views
Last Modified: 2008-02-01
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
0
Comment
Question by:dkim18
  • 5
  • 3
8 Comments
 
LVL 11

Expert Comment

by:Babycorn-Starfish
ID: 20320085
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
 
LVL 11

Accepted Solution

by:
Babycorn-Starfish earned 500 total points
ID: 20320303
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
 

Author Comment

by:dkim18
ID: 20320792
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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 11

Expert Comment

by:Babycorn-Starfish
ID: 20321372
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
 

Author Comment

by:dkim18
ID: 20322817
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
 
LVL 11

Expert Comment

by:Babycorn-Starfish
ID: 20323086
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
 

Author Comment

by:dkim18
ID: 20323794
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
 
LVL 11

Expert Comment

by:Babycorn-Starfish
ID: 20324300
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

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
In a recent question (https://www.experts-exchange.com/questions/28997919/Pagination-in-Adobe-Acrobat.html) here at Experts Exchange, a member asked how to add page numbers to a PDF file using Adobe Acrobat XI Pro. This short video Micro Tutorial sh…

815 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now