Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Windows Forms
  4. Custom control help!

Custom control help!

Scheduled Pinned Locked Moved Windows Forms
graphicscsshelp
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    venomation
    wrote on last edited by
    #1

    The following code is meant to draw a grid and is a custom control (one that can be dragged from the toolbox) :

    public partial class UserControl1 : UserControl
    {
    public UserControl1()
    {
    InitializeComponent();
    AutoScroll = true;

        }
    
        Point \_rowColumn;
        Point \_widthHeight;
        Rectangle\[,\] \_bound;
    
        public void Init(int x, int y, int width, int height)
        {
            SetAutoSizeMode(AutoSizeMode.GrowAndShrink);
          
            \_rowColumn = new Point(x, y);
            \_bound = new Rectangle\[x, y\];
            \_widthHeight = new Point(width, height);
            \_drawArea = new Bitmap(Width, Height);
            LoadTiles();
            \_loaded = true;
    
            AutoScrollMinSize = new Size(x \* width, y \* height);
        }
    
    
    
        void LoadTiles()
        {
            for (int x = 0; x < \_rowColumn.X; x++)
            {
                for (int y = 0; y < \_rowColumn.Y; y++)
                {
                    \_bound\[x, y\] = new Rectangle(x\* \_widthHeight.X, y\*\_widthHeight.Y, \_widthHeight.X, \_widthHeight.Y);
                }
            }
        }
    
        Bitmap \_drawArea;
        bool \_loaded = false;
        void DrawGrid()
        {
            Graphics gfx = Graphics.FromImage(\_drawArea);
            gfx.Clear(Color.White);
            Pen pen = new Pen(Color.Black,1);
    
            foreach (Rectangle r in \_bound)
            {
                gfx.DrawRectangle(pen, r);
            }
    
            gfx.Dispose();
       
    
         
        }
    
        protected override void OnPaint(PaintEventArgs e)
        {
           
            base.OnPaint(e);
            e.Graphics.Clear(Color.White);
    
            Matrix mx = new Matrix(1, 0, 0, 1, AutoScrollPosition.X, AutoScrollPosition.Y);
    
            e.Graphics.Transform = mx;
    
    
            e.Graphics.PageUnit = GraphicsUnit.Pixel;
            if (!\_loaded) return;
          
            DrawGrid();
            Graphics gfx = e.Graphics;
    
            gfx.DrawImage(\_drawArea, -AutoScrollPosition.X, -AutoScrollPosition.Y, \_drawArea.Width, \_drawArea.Height);
            gfx.Dispose();
            
           
        }
    
        private void UserControl1\_Paint(object sender, PaintEventArgs e)
        {
    
            
        }
    }
    

    It displays everything but for some reason when I scroll the lines distort! Here is a link of what it looks like without scrollin

    L 1 Reply Last reply
    0
    • V venomation

      The following code is meant to draw a grid and is a custom control (one that can be dragged from the toolbox) :

      public partial class UserControl1 : UserControl
      {
      public UserControl1()
      {
      InitializeComponent();
      AutoScroll = true;

          }
      
          Point \_rowColumn;
          Point \_widthHeight;
          Rectangle\[,\] \_bound;
      
          public void Init(int x, int y, int width, int height)
          {
              SetAutoSizeMode(AutoSizeMode.GrowAndShrink);
            
              \_rowColumn = new Point(x, y);
              \_bound = new Rectangle\[x, y\];
              \_widthHeight = new Point(width, height);
              \_drawArea = new Bitmap(Width, Height);
              LoadTiles();
              \_loaded = true;
      
              AutoScrollMinSize = new Size(x \* width, y \* height);
          }
      
      
      
          void LoadTiles()
          {
              for (int x = 0; x < \_rowColumn.X; x++)
              {
                  for (int y = 0; y < \_rowColumn.Y; y++)
                  {
                      \_bound\[x, y\] = new Rectangle(x\* \_widthHeight.X, y\*\_widthHeight.Y, \_widthHeight.X, \_widthHeight.Y);
                  }
              }
          }
      
          Bitmap \_drawArea;
          bool \_loaded = false;
          void DrawGrid()
          {
              Graphics gfx = Graphics.FromImage(\_drawArea);
              gfx.Clear(Color.White);
              Pen pen = new Pen(Color.Black,1);
      
              foreach (Rectangle r in \_bound)
              {
                  gfx.DrawRectangle(pen, r);
              }
      
              gfx.Dispose();
         
      
           
          }
      
          protected override void OnPaint(PaintEventArgs e)
          {
             
              base.OnPaint(e);
              e.Graphics.Clear(Color.White);
      
              Matrix mx = new Matrix(1, 0, 0, 1, AutoScrollPosition.X, AutoScrollPosition.Y);
      
              e.Graphics.Transform = mx;
      
      
              e.Graphics.PageUnit = GraphicsUnit.Pixel;
              if (!\_loaded) return;
            
              DrawGrid();
              Graphics gfx = e.Graphics;
      
              gfx.DrawImage(\_drawArea, -AutoScrollPosition.X, -AutoScrollPosition.Y, \_drawArea.Width, \_drawArea.Height);
              gfx.Dispose();
              
             
          }
      
          private void UserControl1\_Paint(object sender, PaintEventArgs e)
          {
      
              
          }
      }
      

      It displays everything but for some reason when I scroll the lines distort! Here is a link of what it looks like without scrollin

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi again, the problem with AutoScroll is Windows, while scrolling, will copy and move that part of the painting that it can reuse, and order your Paint handler to only paint the new stuff, the part that becomes visible by scrolling. And that interferes with your intentions. Furthermore, your code is much too complex; you are using an image, there is no need for, nor advantage in, doing that. Here is a simple example that works well; I use a specialized panel to get double-buffering, and I invalidate the (entire) panel when scrolling, forcing an all-paint, no-copy approach.

      	Panel p;
      	int nHor=40;
      	int nVert=10;
      	int wid=20;
      	int hei=20;
      	public void Demo() {
      		Form f=new Form();
      		f.Bounds=new Rectangle(0, 0, 500, 500);
      		p=new UserDrawnPanel();
      		// or p=new Panel();
      		p.Bounds=new Rectangle(20, 20, 400, 400);
      		p.AutoScroll=true;
      		p.AutoScrollMinSize=new Size(nHor\*wid+10, nVert\*hei+10);
      		p.BackColor=Color.White;
      		p.Paint+=new PaintEventHandler(p\_Paint);
      		p.Scroll+=new ScrollEventHandler(p\_Scroll);
      		f.Controls.Add(p);
      		f.Show();
      	}
      
      	void p\_Scroll(object sender, ScrollEventArgs e) {
      		log("Scroll="+e.NewValue);
      		p.Invalidate();
      	}
      
      	void p\_Paint(object sender, PaintEventArgs e) {
      		Graphics g=e.Graphics;
      		log("ClipRectangle="+e.ClipRectangle);
      		log("AutoScrollPosition="+p.AutoScrollPosition);
      		g.TranslateTransform(p.AutoScrollPosition.X, p.AutoScrollPosition.Y);
      		for (int y=0; y<=nVert; y++) g.DrawLine(Pens.Black, 0, y\*hei, nHor\*wid, y\*hei);
      		for (int x=0; x<=nHor ; x++) g.DrawLine(Pens.Black, x\*wid, 0, x\*wid, nVert\*hei);
      	}
      
      	class UserDrawnPanel : Panel {
      		public UserDrawnPanel() {
      			SetStyle(ControlStyles.UserPaint, true);
      			SetStyle(ControlStyles.AllPaintingInWmPaint, true);
      			SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
      		}
      	}
      

      BTW: you can safely ignore the log statements. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

      Please use < PRE > tags for code snippets, it preserves indentation, and improves readability.

      V 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi again, the problem with AutoScroll is Windows, while scrolling, will copy and move that part of the painting that it can reuse, and order your Paint handler to only paint the new stuff, the part that becomes visible by scrolling. And that interferes with your intentions. Furthermore, your code is much too complex; you are using an image, there is no need for, nor advantage in, doing that. Here is a simple example that works well; I use a specialized panel to get double-buffering, and I invalidate the (entire) panel when scrolling, forcing an all-paint, no-copy approach.

        	Panel p;
        	int nHor=40;
        	int nVert=10;
        	int wid=20;
        	int hei=20;
        	public void Demo() {
        		Form f=new Form();
        		f.Bounds=new Rectangle(0, 0, 500, 500);
        		p=new UserDrawnPanel();
        		// or p=new Panel();
        		p.Bounds=new Rectangle(20, 20, 400, 400);
        		p.AutoScroll=true;
        		p.AutoScrollMinSize=new Size(nHor\*wid+10, nVert\*hei+10);
        		p.BackColor=Color.White;
        		p.Paint+=new PaintEventHandler(p\_Paint);
        		p.Scroll+=new ScrollEventHandler(p\_Scroll);
        		f.Controls.Add(p);
        		f.Show();
        	}
        
        	void p\_Scroll(object sender, ScrollEventArgs e) {
        		log("Scroll="+e.NewValue);
        		p.Invalidate();
        	}
        
        	void p\_Paint(object sender, PaintEventArgs e) {
        		Graphics g=e.Graphics;
        		log("ClipRectangle="+e.ClipRectangle);
        		log("AutoScrollPosition="+p.AutoScrollPosition);
        		g.TranslateTransform(p.AutoScrollPosition.X, p.AutoScrollPosition.Y);
        		for (int y=0; y<=nVert; y++) g.DrawLine(Pens.Black, 0, y\*hei, nHor\*wid, y\*hei);
        		for (int x=0; x<=nHor ; x++) g.DrawLine(Pens.Black, x\*wid, 0, x\*wid, nVert\*hei);
        	}
        
        	class UserDrawnPanel : Panel {
        		public UserDrawnPanel() {
        			SetStyle(ControlStyles.UserPaint, true);
        			SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        			SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        		}
        	}
        

        BTW: you can safely ignore the log statements. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

        Please use < PRE > tags for code snippets, it preserves indentation, and improves readability.

        V Offline
        V Offline
        venomation
        wrote on last edited by
        #3

        Thanks again it works well :-D

        L 1 Reply Last reply
        0
        • V venomation

          Thanks again it works well :-D

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          you're welcome. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use < PRE > tags for code snippets, it preserves indentation, and improves readability.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups