Transparent child form in parent form with transparency and background - c#

I have a form with background image and transparency key.
In that form I put child form which must be fully transparent to show bakground of the parent form. If I set another transparency key to child form - it do not get transparency at all, and if i set transparency key of parent form - child cut through parent form's background image.
I need to use form - not user control so thats an issue. And i dont want to set dublicate background image to child form.
Im working visually. Here's code from designer:
That is my parent
//
// Main
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.DarkRed;
this.BackgroundImage = global::NWN_Tsuki.Properties.Resources.Book;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.ClientSize = new System.Drawing.Size(800, 665);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.CloseBtn);
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.KeyPreview = true;
this.MaximumSize = new System.Drawing.Size(800, 665);
this.MinimumSize = new System.Drawing.Size(800, 665);
this.Name = "Main";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Header";
this.TransparencyKey = System.Drawing.Color.DarkRed;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Main_KeyDown);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Main_MouseDown);
this.tableLayoutPanel1.ResumeLayout(false);
this.ResumeLayout(false);
That is how I insert child into parent's panel:
private void LeftPanel_Paint(object sender, PaintEventArgs e) {
ToC toc = new ToC();
toc.TopLevel = false;
toc.AutoScroll = true;
this.LeftContent.Controls.Add(toc);
toc.FormBorderStyle = FormBorderStyle.None;
toc.Dock = DockStyle.Fill;
toc.Show();
}
Here is my Child:
//
// ToC
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Silver;
this.ClientSize = new System.Drawing.Size(428, 396);
this.Controls.Add(this.Ch7Btn);
this.Controls.Add(this.Ch6Btn);
this.Controls.Add(this.Ch5Btn);
this.Controls.Add(this.Ch4Btn);
this.Controls.Add(this.Ch3Btn);
this.Controls.Add(this.Ch2Btn);
this.Controls.Add(this.Ch1Btn);
this.Controls.Add(this.label1);
this.Name = "ToC";
this.Text = "ToC";
this.TransparencyKey = System.Drawing.Color.Silver;
this.ResumeLayout(false);
Thats the situation when child is Silver inside parent now matter that it has transparency key Silver.
If i set this.BackColor = System.Drawing.Color.DarkRed; to Child - it will pierce parent's background.
Here's some images of what i mean.
Child with other then parent transparency key
Child with same as parent transparency

I am not sure why your child form's background is piercing the main form.
There are two things you might try.
try setting both to a different color which your are most likely not going to use. Like Color.Magenta. (Altough I understand that you might have tried this already)
You should be able to set the Back color to transparent here
Button1.BackColor = Color.Transparent;

Related

How to get a Label with AutoSize to update its Position while anchored to the Right?

I have a simple System.Windows.Forms.Label in a System.Windows.Forms.Form.
I want to dynamically resize the label to fit text loaded runtime, while keeping it Anchored to the right and bottom of its parent form.
According to the MSDN Documentation:
It is “always true” that the Location Property remains constant (i.e., that the top left position of the Control will never change).
It is “always true” that the Anchor property is respected when AutoSize is true (i.e., that the Location Property—the top-left corner—will be modified so that the Anchored Sides maintain their initial distance from the edges of their parent controls).
From my reading of this, I would expect that the second truth overrides the first when Anchor is anything but AnchorStyles.None.
However, this doesn't seem to bear out in practice.
Consider the following:
// From ExampleForm.Designer.cs
this.label = new System.Drawing.Label();
this.label.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.label.AutoSize = true;
this.label.Location = new System.Drawing.Point(600, 400);
this.label.Size = new System.Drawing.Size(170, 20);
this.label.Text = "[Populated at Runtime]";
this.label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
// ...
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.label);
// ...
// Sometime after Form Initialization, this is called
void PopulateLabel() {
var oldRight = label.Right;
label.Text = "Hey here's some new text. It's pretty long so the control will have to resize";
// Without this next line, the Right Anchor distance is not maintained.
// label.Left -= (label.Right - oldRight);
System.Diagnostics.Debug.Assert(label.Anchor.HasFlag(AnchorStyles.Right) && label.Right == oldRight, "The label didn't stay anchored to the right");
}
Obviously I can work around this by tracking the distance manually, as above.
I just wonder if there isn't some way this is “supposed” to work that I'm doing wrong.
The one observation I have to offer is this: it works if the label is not anchored to the bottom.
Do I need to call Suspend/Resume/PerformLayout on the Label? on the Form?
Are the docs wrong?
Am I being foolishly naïve or completely misunderstanding something?
Do I need some sort of intermediary Control for this to work and the docs assume I know this?
To address some possible complications that show up in similar questions (or that I dreamt up):
rightToLeft is false,
Dock is DockStyle.None,
the label's Parent is the form itself, not an intermediary panel or other control.
the Margin seems irrelevant
Anchoring to the Top or Bottom seems irrelevant to Right not working.
System.Windows.Form.Button works as expected. I haven't tested other controls.
Try using a TableLayout, it tends to obey the Control layout properties better. E.g:
public class MyForm : Form {
Label label = new Label() { BackColor = Color.Blue, ForeColor = Color.White };
public MyForm() {
TableLayoutPanel panel = new TableLayoutPanel() { BackColor = Color.Green };
panel.ColumnCount = 1;
panel.RowCount = 1;
panel.Controls.Add(label, 0, 0);
panel.Dock = DockStyle.Bottom;
panel.AutoSize = true;
panel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
panel.Controls.Add(label);
//this.label.Anchor = AnchorStyles.Right | AnchorStyles.Top;// | AnchorStyles.Bottom; // ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
//this.label.Dock = DockStyle.Fill;
this.label.Dock = DockStyle.Right;
this.label.AutoSize = true;
this.label.Margin = Padding.Empty;
//this.label.Location = new System.Drawing.Point(600, 400);
//this.label.Size = new System.Drawing.Size(170, 20);
this.label.Text = "[Populated at Runtime]";
//this.label.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
// ...
//this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
//this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
//this.Controls.Add(this.label);
this.Controls.Add(panel);
// ...
Button btn = new Button { Text = "Change text" };
btn.Click += delegate {
PopulateLabel();
};
Controls.Add(btn);
}
// Sometime after Form Initialization, this is called
void PopulateLabel() {
var oldRight = label.Right;
label.Text = "Hey here's some new text. It's pretty long so the control will have to resize";
// Without this next line, the Right Anchor distance is not maintained.
// label.Left -= (label.Right - oldRight);
//System.Diagnostics.Debug.Assert(label.Anchor.HasFlag(AnchorStyles.Right) && label.Right == oldRight, "The label didn't stay anchored to the right");
}
}

The size of picturebox is different than what was initialized as

Just for testing I have created a new windows forms project with a picturebox on the form and changed the size of it to 100x100. This is the InitializeComponents function:
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Location = new System.Drawing.Point(13, 13);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(100, 100);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.pictureBox1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}
This is my From1_Load function:
private void Form1_Load(object sender, EventArgs e)
{
MessageBox.Show(pictureBox1.Size.ToString());
}
And this is what I get when I run the app:
Why do I get width=67 height= 65 when it is clear in init that it was meant to be 100x100?
My monitor res is 3840x2160 with change of size of text as 125% Tweaking these settings do not change the result.
Add an image reference.
pictureBox1.Image = Properties.Resources.myImage;
See what happens then, I just need more information to help...

Winform Designer border glitch in Windows 10

i have a PictureBoxin a Form, Dock Property of PictureBox is set to Fill.
now to keep only borders of the form, i set ControlBox property to false and FormBorderStyle to SizableToolWindow.
in Windows 7, it looks like below
but in Windows 10 same code looks like below
can anybody explain why this white border appears at top? i tried removing padding, margin & Rebuild Solution. none of that helped!
in windows 10 (Visual Studio 2015, Designer) form looks normal (without white top border)
.Net target framework version: v4.6
P.S: Image taken from here
Update: here's the Windows Form Designer generated code
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Preview_Image));
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(284, 261);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
//
// Preview_Image
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.ControlBox = false;
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow;
this.Name = "Preview_Image";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
}

WebBrowser (win form) opacity

I have a system windows forms web browser on top of another control. The web browser has an image set.
On top of the web browser control is an inherited panel where I can control the opacity.
If I make this transparent, it doesn't show the web browser image, it shows the back colour of the control under the web browser.
Ie
Layer1 control. Back colour is blue
Layer2 web browser with image as HTML
Layer3 transparent panel
Layer3 when transparent shows layer1 not layer2
How can I make the web browser opaque so layer3 shows through to layer2 (webbrowser) ?
I have tried setting SetStyles to control opacity on the web browser.
Thanks
Short Answer:
You can't.
Real World Solution:
Have you looked into WPF?
Long Answer:
Opacity is a trick that WinForms does.
When a control is marked to be displayed transparent (or semi transparent), WinForms queries the parent object's visuals to ask "What would you have printed here had my control not existed?". From this result WinForms either displays the pixel of the control, the pixel of the parent, or a combination of the two (if semi transparent).
This becomes really apparent in a simple example:
Create a new winforms project
Create 2 labels, place them over top of each other (slighty offset)
Set both labels backgrounds to Color.Transparent
You'll see immediately that transparency takes a chunk out of the label underneath.
Example Code (All in one file, compile and run):
using System;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApplication5
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
public class MainForm : Form
{
private Random random = new Random();
private Button btnRandomBackgroundColor;
private Label lblBackgroundLabel;
private Label lblTransparent;
public MainForm()
{
InitializeComponent();
}
private void button_Click(object sender, EventArgs e)
{
BackColor = Color.FromArgb(random.Next(0, 255),
random.Next(0, 255),
random.Next(0, 255));
}
private void InitializeComponent()
{
this.btnRandomBackgroundColor = new System.Windows.Forms.Button();
this.lblBackgroundLabel = new System.Windows.Forms.Label();
this.lblTransparent = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// btnRandomBackgroundColor
//
this.btnRandomBackgroundColor.Location = new System.Drawing.Point(12, 12);
this.btnRandomBackgroundColor.Name = "btnRandomBackgroundColor";
this.btnRandomBackgroundColor.Size = new System.Drawing.Size(144, 23);
this.btnRandomBackgroundColor.TabIndex = 0;
this.btnRandomBackgroundColor.Text = "Randomize Background Color";
this.btnRandomBackgroundColor.UseVisualStyleBackColor = true;
this.btnRandomBackgroundColor.Click += button_Click;
//
// lblBackgroundLabel
//
this.lblBackgroundLabel.AutoSize = true;
this.lblBackgroundLabel.BackColor = System.Drawing.Color.Transparent;
this.lblBackgroundLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblBackgroundLabel.Location = new System.Drawing.Point(41, 49);
this.lblBackgroundLabel.Name = "lblBackgroundLabel";
this.lblBackgroundLabel.Size = new System.Drawing.Size(184, 33);
this.lblBackgroundLabel.TabIndex = 1;
this.lblBackgroundLabel.Text = "Simple Label";
//
// lblTransparent
//
this.lblTransparent.AutoSize = true;
this.lblTransparent.BackColor = System.Drawing.Color.Transparent;
this.lblTransparent.Font = new System.Drawing.Font("Microsoft Sans Serif", 21.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTransparent.Location = new System.Drawing.Point(61, 63);
this.lblTransparent.Name = "lblTransparent";
this.lblTransparent.Size = new System.Drawing.Size(251, 33);
this.lblTransparent.TabIndex = 2;
this.lblTransparent.Text = "Transparent Label";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(341, 114);
Controls.Add(this.lblTransparent);
this.Controls.Add(this.lblBackgroundLabel);
this.Controls.Add(this.btnRandomBackgroundColor);
this.Name = "Form1";
this.Text = "MainForm";
this.ResumeLayout(false);
this.PerformLayout();
}
}
}

Panel scroll vertically

I have a winform app in which I have a panel control.
I want to be able to scroll inside the panel and place controls vertically more then the current height of the control and then have a scroll which will help me to see all the controls, how can I achieve that?
This is the designer code as well, in case someone wants to take a look at the code:
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.SuspendLayout();
//
// panel1
//
this.panel1.AutoScroll = true;
this.panel1.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(267, 365);
this.panel1.TabIndex = 0;
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(456, 410);
this.Controls.Add(this.panel1);
this.Name = "Form2";
this.Text = "Form2";
this.ResumeLayout(false);
}
Since you have AutoScroll = true, you shouldn't have to do anything. Any control that you place in the panel that is below the visible boundary will automatically create the appropriate scroll distance in the panel.
If you want to manually override that, set AutoScroll = false and set the size of the canvas yourself using the AutoScrollMinSize property, example:
panel1.AutoScrollMinSize = new Size(0, 1200);
You might want to consider anchoring the panel to the four sides of the form as well, or dock-fill, since it looks like a resizable form. Again, the panel will handle the scrollbar size for you.
Try this out for loading other forms in panels of MDIForm. It works perfectly.
myForm.TopLevel = false;
myForm.AutoScroll = true;
main_panel.Controls.Clear();
main_panel.Controls.Add(myForm);
main_panel.AutoScrollMinSize = new Size(0, myForm.Height);
myForm.Show();

Categories