c# - Allow custom control to correctly scroll out of view -


i have custom control consists of filled rounded rectangle text. (the actual control more complicated code shown here has sames symptoms.) attached instances of control panel, , made panel child of panel autoscroll = true. thought enough correct scroll behavior, if scroll such left side of control should go off left side of panel sticks , control shrinks. same scrolling such control should go off @ top. (bottom , right seem not problem.) here sample code (requires reference system.windows.forms , system.drawing.) using visual studio 2010 .net 4 client on windows.

using system; using system.drawing; using system.drawing.drawing2d; using system.windows.forms;   namespace customcontrolscrolltest {     static class program     {         [stathread]         static void main()         {             application.enablevisualstyles();             application.setcompatibletextrenderingdefault(false);             application.run(new form1());         }     }      // form dock = fill panel autoscroll turned on, , nested panel     // few custom roundrectcontrols.     public class form1 : form     {         panel autoscrollpanel;         panel rectpanel;          public form1()         {             size = new size(300, 200);              autoscrollpanel = new panel();             autoscrollpanel.dock = dockstyle.fill;             autoscrollpanel.autoscroll = true;             autoscrollpanel.autoscrollminsize = new size(600, 450);              autoscrollpanel.resize += autoscrollpanel_resize;             autoscrollpanel.scroll += autoscrollpanel_scroll;              controls.add(autoscrollpanel);              rectpanel = new panel();             rectpanel.size = autoscrollpanel.autoscrollminsize;             rectpanel.controls.addrange(new roundrectcontrol[] {                 new roundrectcontrol(),                 new roundrectcontrol(),                 new roundrectcontrol(),                 new roundrectcontrol(),                 new roundrectcontrol()             });              foreach (control c in rectpanel.controls)             {                 c.click += c_click;             }              autoscrollpanel.controls.add(rectpanel);              placeboxes();         }          // want able recalculate boxes position @ time         // in real program occurs due model changes         void c_click(object sender, eventargs e)         {             placeboxes();         }          void autoscrollpanel_scroll(object sender, scrolleventargs e)         {             refresh();         }          void autoscrollpanel_resize(object sender, eventargs e)         {             refresh();         }          private void placeboxes()         {             (int = 0; < rectpanel.controls.count; ++i)             {                 int j = + 1;                 var node = rectpanel.controls[i] roundrectcontrol;                 if (node != null)                 {                     node.title = "hello (" + j + ")";                     node.location = new point(i * 100, j * 75);                     node.visible = true;                                    }             }         }     }      // rounded rectangle filled blue black border , white text     // size determined text     public class roundrectcontrol : control     {         public roundrectcontrol()         {             var f = systemfonts.messageboxfont;             titlefont = new font(f.name, f.sizeinpoints + 2, fontstyle.bold, graphicsunit.point);             resizeredraw = true;         }          protected override void onpaint(painteventargs e)         {             base.onpaint(e);             var g = e.graphics;              var left = e.cliprectangle.x;             var right = left + titlewidth + 2 * radius;             var top = e.cliprectangle.y;             var bottom = top + nodeheight + 2 * radius;              var r2 = 2 * radius;              using (var path = new graphicspath())             {                 path.addarc(left,       bottom - r2, r2,  r2, 90,  90);                 path.addarc(left,       top,         r2,  r2, 180, 90);                 path.addarc(right - r2, top,         r2,  r2, 270, 90);                 path.addarc(right - r2, bottom - r2, r2,  r2, 0,   90);                 path.closefigure();                  g.fillpath(titlebrush, path);                 g.drawpath(borderpen, path);             }              g.drawstring(title, titlefont, titletextbrush, left + radius, top + radius);         }          private string title;         public string title         {             { return title; }             set             {                 title = value;                 size = getsize();                 invalidate();             }         }          private brush titlebrush = brushes.blue;          private brush titletextbrush = brushes.white;          private pen borderpen = pens.black;          private size getsize()         {             var g = creategraphics();             var titlesize = g.measurestring(title, titlefont);             titlewidth = (int)titlesize.width;             nodeheight = (int)titlesize.height;             return new size(titlewidth + 2 * radius + 1, nodeheight + 2 * radius + 1);         }          public override size getpreferredsize(size proposedsize)         {             return getsize();         }          private int titlewidth;         private int nodeheight;          private font titlefont;          private int radius = 5;     } } 

try this

protected override void onpaint(painteventargs e)     {         base.onpaint(e);         var g = e.graphics;          //total width , height of rounded rectangle         var width = titlewidth + 2 * radius + 1;         var height = nodeheight + 2 * radius + 1;          var left = e.cliprectangle.x;         var top = e.cliprectangle.y;          //check if clipping occurs. if yes, set 0         if (width > e.cliprectangle.width)         {             left = 0; // *= -1;         }          //check if clipping occurs.if yes, set 0         if (height > e.cliprectangle.height)         {             top = 0; // *= -1         }          var right = left + titlewidth + 2 * radius;         var bottom = top + nodeheight + 2 * radius;          var r2 = 2 * radius;          using (var path = new graphicspath())         {             path.addarc(left, bottom - r2, r2, r2, 90, 90);             path.addarc(left, top, r2, r2, 180, 90);             path.addarc(right - r2, top, r2, r2, 270, 90);             path.addarc(right - r2, bottom - r2, r2, r2, 0, 90);             path.closefigure();              g.fillpath(titlebrush, path);             g.drawpath(borderpen, path);         }          g.drawstring(title, titlefont, titletextbrush, left + radius, top + radius);     } 

the problem when scrolling right(rects moving left, e.cliprectangle.width becomes smaller) , rectangle goes out of area, e.cliprectangle.x positive! in case set zero. e.cliprectangle.x can not negative, if invert it(solution before edit) becomes zero.

edit

you can do

var left = 0; var right = left + titlewidth + 2 * radius; var top = 0; var bottom = top + nodeheight + 2 * radius; 

both working

you can use these styles

this.setstyle(controlstyles.doublebuffer, true); this.setstyle(controlstyles.userpaint, true); this.setstyle(controlstyles.allpaintinginwmpaint, true); 

to avoid flickering

valter


Comments

Popular posts from this blog

php - Submit Form Data without Reloading page -

linux - Rails running on virtual machine in Windows -

php - $params->set Array between square bracket -