Solved

Drawing on a panel using solid brush ,,,, overriding onpaint problem

Posted on 2008-10-08
16
2,529 Views
Last Modified: 2013-12-17
Hello there ,,,, I have made a window application , , , it consists of a panel form , from which
you can create a new mdichild window , inside the mdichild window there is a panel
i can draw inside the panel , but the problem is that when i minimize the child form and maximize it
everything i painted on it dissapears
so what should i write exactly in the onpaint
private void panel1_MouseUp(object sender, MouseEventArgs e)

        {

            shouldpaint = false;

        }

  private void panel1_MouseDown(object sender, MouseEventArgs e)

        {

            shouldpaint = true;

        }

 

  private void panel1_MouseMove(object sender, MouseEventArgs e)

        {

            if (shouldpaint)

            {

                Graphics graphics =  panel1.CreateGraphics();

                graphics.FillEllipse(frm.Mybrush,e.X,e.Y,frm.XX,frm.YY);

                graphics.Dispose();

            }

        }

 

     protected override void OnPaint (PaintEventArgs pe)

                {

                

                        

                }

Open in new window

0
Comment
Question by:nikorba
  • 9
  • 7
16 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22671214
this is the expected behaviour, the windows don't have a "memory" about what you paint.
That's why you have to put your paint operations at the OnPaint event to repaint it every time it is needed.
0
 
LVL 2

Author Comment

by:nikorba
ID: 22672988
Hi jaime , thanx for your comment , i know that it's expected behaviour ,,, but i wanna know how i can change it  ,, ,
again i tried this but it didnt work



  private void panel1_MouseMove(object sender, MouseEventArgs e)

        {

            xxx = e.X; // just to keep track of the mouse position

            yyy = e.Y;  //although maybe i can use mouseposition.x              

        }
 

 protected override void OnPaint (PaintEventArgs pe)

                {

                   if (shouldpaint)

                    {
 

                        Graphics graphics = panel1.CreateGraphics();
 

                        graphics.FillEllipse(frm.Mybrush, xxx,yyy, frm.XX, frm.YY);
 

                        graphics.Dispose();
 

                   }

                        

                }

Open in new window

0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22673589
You don't need to create a Graphics object, there is an existing at 'pe' argument:

                protected override void OnPaint (PaintEventArgs pe)
                {
                    if (shouldpaint)
                    {
                        pe.Graphics.FillEllipse(frm.Mybrush, xxx,yyy, frm.XX, frm.YY);
                    }
                }
0
 
LVL 2

Author Comment

by:nikorba
ID: 22673775
it didnt work :(
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22674911
OnPaint always work. Unless you have undesired values in your xx, yy variables, Or maybe shouldpaint = false
0
 
LVL 2

Author Comment

by:nikorba
ID: 22683012
but it didnt :(  , , , ,
shouldnt i call the onpaint  , from the mouse move event ? ? ? ?
i also tried using the panel1.invalidate to call the onpaint but ,,, nothing's new
SO any Idea?
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22683155
Oh, I see your problem, just need to force repainting:

private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            xxx = e.X; // just to keep track of the mouse position
            yyy = e.Y;  //although maybe i can use mouseposition.x              
this.Invalidate();  // or this.Refresh();
        }
 
0
 
LVL 2

Author Comment

by:nikorba
ID: 22686956
Hi buddy , again thanx for ur help ,,,
here is the code ,,, what's wrong with it ?
it's not working also
i can paint on the panel but the onpaint event is not working
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;
 

namespace usingMDI

{

    public partial class Panel : Form

    {

        bool shouldpaint = false;

        Form1 frm = (Form1)ActiveForm;
 

        int xxx ;

        int yyy ;

        

        public Panel()

        {

            InitializeComponent();          

        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)

        {

            shouldpaint = true;

        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)

        {

            xxx = e.X;

            yyy = e.Y;

           

            if (shouldpaint)

            {

                Graphics graphics =  panel1.CreateGraphics();

                graphics.FillEllipse(frm.Mybrush, e.X, e.Y, frm.XX, frm.YY);

                graphics.Dispose();

                this.Invalidate();

                

            }          

        }

            protected override void OnPaint (PaintEventArgs pe)

                {

                   if (shouldpaint)

                   {  

                      pe.Graphics.FillEllipse(frm.Mybrush, xxx,yyy, frm.XX, frm.YY);

                   }                     

                }
 

        private void panel1_MouseUp(object sender, MouseEventArgs e)

        {

            shouldpaint = false;

        }

 

            }
 

    }

Open in new window

0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22688497
try with the following:
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

 

namespace usingMDI

{

    public partial class Panel : Form

    {

        bool shouldpaint = false;

//        Form1 frm = (Form1)ActiveForm;

        Brush myBrush = Brushes.Black;

 

        int xxx ;

        int yyy ;

        

        public Panel()

        {

            InitializeComponent();          

        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)

        {

            shouldpaint = true;

        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)

        {

            xxx = e.X;

            yyy = e.Y;

           

            if (shouldpaint)

                this.Invalidate();

        }

        protected override void OnPaint (PaintEventArgs e)

        {

             if (shouldpaint)

             {  

                  e.Graphics.FillEllipse(this.Mybrush, xxx,yyy, 10, 10); // frm.XX, frm.YY);

             }                     

        }

 

        private void panel1_MouseUp(object sender, MouseEventArgs e)

        {

            shouldpaint = false;

        }

    }

}

Open in new window

0
 
LVL 2

Author Comment

by:nikorba
ID: 22689034
I tried it ,,, i couldnt even paint , , , on the panel.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22689317
does any ellipse appears on your form?
are you event methods really tied to your events?
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22689328
maybe you can test this tutorial application:
http://www.csharphelp.com/archives/archive222.html
0
 
LVL 2

Author Comment

by:nikorba
ID: 22749801
Hi , i saw the tutorial application and it was disappointing that the programmer has declared more than 1000 rectangle in order to fit the paint on a form ,,,, check it out  ,
i dont wanna declare hundreds of recrangles inorder to be able to paint on the panel ,,,,
i know that i gotta use the paint method , and i know that it works painting a square or rectangle or fixed shape and i know how !, ,, , , , but i dont know how to use it for hand painting using a mouse move :S
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22749886
I think you still don't understand the painting paradigm. it is basically vector oriented, so real paint is not stored on memory, but it repaints all the drawing everytime onPaint is invoked. That's why painting is saved into several rectangles.
Another alternative is to paint into a bitmap, not to screen, with every mouse action, then at onPaint event, just show the bitmap everytime it is required. This approach is used by photo-retouching-like software.
So your best chance is to look into such kind of code sample.
0
 
LVL 2

Author Comment

by:nikorba
ID: 22814343
my sage brother , im not solving a home work  , , , would you please lead me to a sample or give me a solution to this problem ,,,
because saving in rectangles didnt suit me best!!
Again thank you
0
 
LVL 55

Accepted Solution

by:
Jaime Olivares earned 500 total points
ID: 22817867
well, there are several steps to do this. first declare a bitmap object as a Form's member:

Bitmap thePicture;

create it somewhere as:

thePicture = new Bitmap(someWidth,  someHeight, PixelFormat.Format32bppPArgb);

then, every time you want to paint, do not paint to the screen, do it on the bitmap, as:

using (Graphics graphics = Graphics.FromImage(thePicture))
{
    graphics.SomePaintMethodHere(.....);
}

this is done off-side the screen, so you need to force the painting on screen with Invalidate();
the real paint will be done at the OnPaint event, so you will need to do something like:

protected override void OnPaint (PaintEventArgs pe)
{
// always should paint

       using (Graphics graphics = panel1.CreateGraphics())
       {
             graphics.DrawImage(thePicture, 0, 0);
       }
}
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

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…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.

895 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