c# - How to draw line and select it in Panel -
my program can draw lines using canvas.drawline(). how click line , change color (select line)?
private list<point> coordfirst = new list<point>(); private list<point> coordlast = new list<point>(); public graphics canvas; private void form1_load(object sender, eventargs e) { canvas=panel1.creategraphics(); }
coordinate line stored in coordfirs & coodlast.
here suitable line
class:
class line { public color linecolor { get; set; } public float linewidth { get; set; } public bool selected { get; set; } public point start { get; set; } public point end { get; set; } public line(color c, float w, point s, point e) { linecolor = c; linewidth = w; start = s; end = e; } public void draw(graphics g) { using (pen pen = new pen(linecolor, linewidth)) g.drawline(pen, start, end); } public bool hittest(point pt) { // test if fall outside of bounding box: if ((pt.x < start.x && pt.x < end.x) || (pt.x > start.x && pt.x > end.x) || (pt.y < start.y && pt.y < end.y) || (pt.y > start.y && pt.y > end.y)) return false; // calculate distance: float dy = end.y - start.y; float dx = end.x - start.x; float z = dy * pt.x - dx * pt.y + start.y * end.x - start.x * end.y; float n = dy * dy + dx * dx; float dist = (float)( math.abs(z) / math.sqrt(n)); // done: return dist < linewidth / 2f; } }
define list lines, @ class level:
list<line> lines = new list<line>();
here how can initialize few lines:
for (int = 0; < 20; i++) lines.add(new line(color.black, 4f, new point(r.next(panel1.width), r.next(panel1.height)), new point(r.next(panel1.width), r.next(panel1.height))));
here result of clicking on crossing:
whenever add, change or remove line need make panel
reflect news triggering paint
event:
panel1.invalidate();
here paint
event of panel
:
private void panel1_paint(object sender, painteventargs e) { e.graphics.smoothingmode = smoothingmode.antialias; foreach (line l in lines) l.draw(e.graphics); }
in mouseclick
event test:
private void panel1_mouseclick(object sender, mouseeventargs e) { foreach(line l in lines) l.linecolor = l.hittest(e.location) ? color.red : color.black; panel1.invalidate(); }
to avoid flicker don't use basic panel
class isn't doublebuffered
. instead use either picturebox
or doublebuffered panel
subclass:
class drawpanel : panel { public drawpanel () { doublebuffered = true; } }
notes:
there no such thing 'line' in winforms, pixels of various colors. select line need store it's 2 endpoints' coordinates , find out if have hit when clicking.
the above example shows how in math.
instead 1 test each line drawing onto bitmap , test pixel mouse has clicked. drawing bitmaps have math behind scenes , allocate space bitmaps, math more efficient..
yes
line
class looks little long such simple thing s line how short event codes are! that's because responsiblities belong!also note the first rule of doing drawing in winforms is: never cache or store
grahics
object. in fact shouldn't ever usecreategraphics
in first place,graphics
object never stay in scope , graphics produces not persist (i.e. survive minimize-maximize sequence)..also note how pass out
e.graphics
object ofpaint
event's parametersline
instances can draw currentgraphics
object!to select thinner lines may modify distance check little..
the math taken directly form wikipedia.
Comments
Post a Comment