Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

draggable line(rectangle) in c #???

Posted on 2007-11-20
8
2,056 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
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.

 
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

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

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

Suggested Solutions

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

839 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