Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

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

Posted on 2008-06-23
1
Medium Priority
?
2,828 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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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…
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand column That will then direct you to their download page. From that p…
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 synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.

604 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