Reputation: 661
I'm trying to draw a semi-transparent background and then opaque elements on top of it.
How come I can't do something like this?
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
this.Opacity = 0.5;
pe.Graphics.FillRectangle(trans_black_brush, square_rect_big);
this.Opacity = 1;
pe.Graphics.FillRectangle(solid_red_brush, square_rect);
}
I'd appreciate if someone with better understanding of Form drawing could tell me why this doesn't work :)
Update: The solution has 3 forms: 1) Main (program, buttons etc) 2) Semi-transparent background (screen size, using opacity) 3) Transparent background but solid brushes on top.
In Form2's constructor, I have this:
Foreground = new FormForeground(this);
and in Form3's constructor I have this:
private Form_FormBackground m_Parent;
public FormForeground(FormBackground parent)
{
InitializeComponent();
FormBackground m_Parent = parent;
...
}
Whenever the mouse is clicked and used to draw with in form 3, I update the parent's rectangle like so:
private void _UpdateParent()
{
m_Parent.s_DrawArea = m_DrawArea;
m_Parent.Invalidate();
}
The parent, form 2 then does its OnPaint() where it draws the marked area.
It does work, however the drawing does lag a bit compared to drawing directly in form3 (which does not produce the desired results because the drawn area needs to be transparent across the forms).
Upvotes: 1
Views: 439
Reputation: 54433
This doesn't work because Opacity
is a Property of the Form
and will always make the whole form and all its content have the current Value. It is perfect for fading a form in or out, though..
You can't achieve what you want with only one form.
Instead you will need two sychronized forms.
One can be somewhat opaque and will let the desktop shine through; the other must be transparent by making use of the TransparencyKey
property and you can draw onto it..
To synchronize the two forms code the Move
and the ResizeEnd
events.
For a first setup use code like this:
A dummy form to create the semi-transparent look:
Form form0 = new Form() { Opacity = 0.33f , BackColor = Color.Black};
In the Form1's Load
event:
TransparencyKey = Color.FromArgb(255, 147, 151, 162);
BackColor = TransparencyKey;
DoubleBuffered = true;
form0.Enabled = false;
form0.BringToFront();
form0.Show();
form0.Size = Size;
form0.Location = Location;
BringToFront();
And in the Move
and the ResizeEnd
events maybe code like this:
private void Form1_Move(object sender, EventArgs e)
{
form0.Size = Size;
form0.Location = Location;
}
private void Form1_ResizeEnd(object sender, EventArgs e)
{
form0.Size = Size;
form0.Location = Location;
}
You also may want to study this post that also shows a way to sandwich two forms.
Note that I picked a rather random color instead of the more common named color Fuchsia
or any named colors. This is because I
Fuchsia
(and possibly some other colors) for some weird legacy reasons..Upvotes: 2