Solved

draggable line(rectangle) in c #???

Posted on 2007-11-20
8
2,020 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
 
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Suggested Solutions

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

762 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

22 Experts available now in Live!

Get 1:1 Help Now