?
Solved

Opacity of a Child Form has OnPaintBackGround issue - Parent painting last!

Posted on 2008-06-23
1
Medium Priority
?
2,815 Views
Last Modified: 2013-12-16
I am creating a "Sheet" which overlays a WinForm and provides a MessageBox like functionality...actually, it's much more interactive...but rather than come up in another window...it comes up inside the WinForm that invokes it...

An important part of the "Sheet" functionality is that it also provides a translucent (Opacity = 50%) covering of the first (Parent) form which provides two key functions:

1.  To "effectively" disable the Parent WinForm's controls by overlaying the "Sheet" form on top of the WinForm.
2.  The Opacity set to 50% gives a visual clue to the user that the controls underneath the "Sheet" are disabled.

Important Notes:
1.  The Sheet cannot use the stock Opacity property...because in order to add this Form (Sheet) to the Parent WinForm, you have to first disable it as a TopLevel Form.

     Sheet.TopLevel = false;

2.  You cannot do Controls.Add to the Sheet Form without setting TopLevel = false;

3.  Microsoft, in their GUI wisdom, decided to disable the Opacity property of all Forms with TopLevel = false;

So my real goal right now is to create child form which can have an Opacity property AND handles window invalidations properly.

I have achieved that goal to some extent by making the child form transparent and then overriding the OnPaintBackGround method and filling the background using an Alpha channel.  

Here is the code which is based on:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2363164&SiteID=1

       protected override CreateParams CreateParams

        {

            get

            {

                CreateParams cp = base.CreateParams;

                cp.ExStyle |= 0x00000020;//WS_EX_TRANSPARENT

                return cp;

            }

        }

 

        private int opacity;
        public int Opacity

        {
            get { return opacity; }

            set {

                opacity = value;

                this.InvalidateEx();

            }

        }

 
        protected override void OnPaintBackground(PaintEventArgs e)
        {
            Color bk = Color.FromArgb(Opacity, this.BackColor);

            e.Graphics.FillRectangle(new SolidBrush(bk), e.ClipRectangle);
        }

        protected void InvalidateEx()
        {

            if (Parent == null)

                return;

            Rectangle rc = new Rectangle(this.Location, this.Size);

            Parent.Invalidate(rc, true);

        }


This actually works great on the first draw...my problem occurs whenever a portion of the Sheet and WinForm Parent are invalidated by another window.  

The problem is that the Sheet gets the OnPaintBackGround event BEFORE the Parent and any other controls on the Parent WinForm.  

PROBLEM: What that means is that the Parent form is drawn last which effectively hides my "Sheet".


I am confused why the child control (Sheet) is handling his OnPaintBackGround before it's parent...this seems very wrong...I know this is the case because I put Debug.Print statements in both the Parent and the child (Sheet)'s OnPaintBackGround methods to see who get's called first.  Further, I tried to make my Sheet WinForm be at the top of the Zorder in two ways:

            parentForm.Controls.Add(this);
       
            parentForm.Controls.SetChildIndex(this, 0);  <-- make sure he is at the top of the Zorder
            sheet.TopMost = true; <-- force him to be TopMost


NOTE:  The OnPaintBackGround is called in the correct order upon the first showing of the WinForm (Parent, other controls lower in the zorder, then the Sheet Form).  The problem only seems to happen when a region is invalidated...


I would be happy to post the project somewhere for you guys to play with and see if you can figure it out...


Any ideas?
0
Comment
Question by:clintcarter1999
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 

Accepted Solution

by:
clintcarter1999 earned 0 total points
ID: 21847034
ok, i figured out a solution...

Rather than override OnPaintBackGround...I decided to override OnPaint (which paints the foreground).
This gaurantee's that the Parent will draw his background before I draw my foreground which gives me what i want.

Works great.  

No need to answer this one guys.  Sorry...
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

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

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
A long time ago (May 2011), I have written an article showing you how to create a DLL using Visual Studio 2005 to be hosted in SQL Server 2005. That was valid at that time and it is still valid if you are still using these versions. You can still re…
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

777 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