Click here to Skip to main content
15,892,575 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,

Last week I posted a question about making labels transparent to eachother. This worked fine with the label and the form itself, but then i found out that the generated labels still aren't transparent to eachother.

After that I decided to try the same with pictureboxes, because i thought they would be more compatible with transparency, besides it's easier to manipulate images in pictureboxes than in labels.

But the result is the same as with the labels, when I generate pictureboxes through code, they are not transparent to each other.

Anyone got a suggestion to fix this?

Greetings,
Rudy

What I have tried:

Public Class TransparentPicturebox
        Inherits PictureBox

        Public Sub New()
            Me.SetStyle(ControlStyles.SupportsTransparentBackColor, True)
            Me.BackColor = Color.Transparent
        End Sub

    End Class


Also, the images I used are fully transparent, else the pictureboxes wouldn't be transparent to the form.
Posted
Updated 9-Apr-18 21:13pm
Comments
Maciej Los 10-Apr-18 3:02am    
I've read somewhere that transparent control have to inherit from Control (base class for each windows controls) instead of Label, PictureBox, etc.
TheRuudster 10-Apr-18 3:15am    
Just tried that, but when i inherit from control instead of a picturebox i'm not able to use the image and sizemode properties which i need. Even if i try to inherit the control and then use backgroundimage (for standard control class instead of image for pictureboxes) there's still no transparency if two pictureboxes overlap. :(

Maybe setting the .parent property of the picturebox will help, see: Transparent Buttons in .NET[^]
 
Share this answer
 
Comments
TheRuudster 10-Apr-18 3:08am    
yeah i tried that sort of, but how would you do that as the controls that have to be transparent to eachother are equal?
RickZeeland 10-Apr-18 3:10am    
I think you can always set the parent, just try it :)
TheRuudster 10-Apr-18 3:54am    
but the .parent property can only be set to an existing control, right? So i don't think that's an option because I create the controls in runtime.
RickZeeland 10-Apr-18 3:58am    
First create both controls in code, then set the .parent property of one of them in code :)
TheRuudster 10-Apr-18 5:30am    

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pic As New TransparentPicturebox With
{
.Visible = True,
.Size = New Drawing.Size(50, 50),
.SizeMode = PictureBoxSizeMode.StretchImage,
.BackColor = Color.Transparent,
.Image = ImageSelect(selection_id),
.Tag = selection_id
}

PictureBox1.Controls.Add(pic)

Dim picList As List(Of TransparentPicturebox) = New List(Of TransparentPicturebox)
For Each c As TransparentPicturebox In PictureBox1.Controls
If (TypeOf c Is TransparentPicturebox) Then
picList.Add(CType(c, TransparentPicturebox))
TextBox4.BackColor = Color.Red
End If

Next
picarray = picList.ToArray



TextBox1.Text = picnum
'picarray(lblnum).BackColor = Color.Red
If picnum > 0 Then
picarray(picnum).Parent = picarray(picnum - 1)
'picarray(lblnum).Parent = PictureBox1
End If



AddHandler pic.MouseDown, AddressOf PictureboxMouseDown
AddHandler pic.MouseMove, AddressOf PictureboxMouseMove
AddHandler pic.MouseUp, AddressOf PictureboxMouseUp
AddHandler pic.MouseWheel, AddressOf PictureboxMouseWheel
AddHandler pic.Click, AddressOf PictureboxMouseClick

TextBox3.Text = selection_id & ", " & picnum.ToString()

picnum = picnum + 1
End Sub


This is my testcode now for trying to make pictureboxes transparent to eachother and it works sort of. The problem is that whenever i add a picturebox, it spawns upon it's parent picturebox and i can't move it in the whole 'drawing area' picturebox anymore xD. So i basically moved the .parent property from the drawing area to another generated picturebox.

Is there a way to set both these elements as a parent for the new added picturebox, so that you can move it in the drawing area and make it transparent to other pictureboxes in the drawin area simultaneously?
Please, read my comment to the question. Here is an implementation of TransparentLabel class (which inherits from Control[^]): C# Transparent Label[^] (found on: Transparent Labels in WinForms - Rick Strahl's Web Log[^])

Another solution is here: WinForms: How to create a control transparent to other controls[^]
 
Share this answer
 
v2
Here is some code that uses SetStyle, it's for a custom button but maybe it can be adapted for a PictureBox:
namespace PushButtonTransparent
{
    using System.Drawing;
    using System.Windows.Forms;
    using System;

    /// <summary>
    ///   Transparent Button with a normal and pressed state, preferably used with transparent .PNG images,
    ///   it can be used without images, in which case only a black rectangle is drawn.
    ///   The click event must be handled by the Form, and property <see cref="pressed"/> must be set.
    ///   This is an extended version of <see cref="PushButton"/> which supports:
    ///   - Transparancy
    ///   - Text
    ///   - Textcolor (ForeColor / <see cref="ForeColorPressed"/>)
    ///   - Font
    /// <example>
    /// <code>
    ///   PushButtonTransparent TransparentButton;
    ///   this.TransparentButton.Text = "Test button";
    ///   // Events, images and colors can be set in the designer, or in code:
    ///   this.TransparentButton.Click += this.ButtonClicked;
    ///   this.TransparentButton.MouseUp += this.PushButtonMouseUp;
    ///   // Set images:
    ///   this.TransparentButton.ImageNotPressed = Loader.LoadBitmap(ResourceId.show_manual);
    ///   this.TransparentButton.ImagePressed = Loader.LoadBitmap(ResourceId.show_manual_over);
    ///   this.TransparentButton.Pressed = true;
    /// </code>
    /// </example>
    /// </summary>
    public class PushButtonTransparent : Control  // , IButtonControl
    {
        private bool pressed;

        /// <summary>
        /// Initializes a new instance of the <see cref="PushButtonTransparent"/> class.
        /// </summary>
        public PushButtonTransparent()
        {
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.Opaque, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            ////this.BackColor = Color.Transparent;
        }

        /// <summary>
        /// Gets or sets imagePressed image.
        /// </summary>
        public Image ImagePressed { get; set; }

        /// <summary>
        /// Gets or sets ImageNotPressed image.
        /// </summary>
        public Image ImageNotPressed { get; set; }

        /// <summary>
        /// Gets or sets TextPosition, otherwise default position is calculated.
        /// </summary>
        public Point TextPosition { get; set; }

        /// <summary>
        /// Gets or sets TextAlignment: Near, Center, Far.
        /// Only if TextPosition is not set.
        /// </summary>
        public StringAlignment TextAlignment { get; set; }

        /// <summary>
        /// Gets or sets ForeColorPressed (text color when clicked).
        /// </summary>
        public Color ForeColorPressed { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether the button is pressed and forces a redraw.
        /// </summary>
        public bool Pressed
        {
            get
            {
                return this.pressed;
            }

            set
            {
                this.pressed = value;
                this.Invalidate();
            }
        }

        /// <summary>
        /// Gets CreateParams and sets WsExTransparent.
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                const int WsExTransparent = 0x20;
                var cp = base.CreateParams;
                cp.ExStyle |= WsExTransparent;
                return cp;
            }
        }

        /// <summary>
        /// Draw ImageNotPressed / ImagePressed if property set.
        /// Draw a black rectangle if image is missing.
        /// Draw Text if property is set.
        /// </summary>
        /// <param name="pevent">
        /// The PaintEventArgs.
        /// </param>
        protected override void OnPaint(PaintEventArgs pevent)
        {
            Image buttonImage;
            var g = pevent.Graphics;
            int width;
            int height;
            SolidBrush textBrush;

            // this.Font = SkinSettings.FontDefault;
            // float scaleFactor = this.Font.Size / 8;

            if (this.pressed)
            {
                buttonImage = this.ImagePressed;
            }
            else
            {
                buttonImage = this.ImageNotPressed;
            }

            if (buttonImage == null)
            {
                // Draw a black rectangle if image is missing.
                width = Convert.ToInt32(this.ClientRectangle.Width * scaleFactor);
                height = Convert.ToInt32(this.ClientRectangle.Height * scaleFactor);
                g.DrawRectangle(Pens.Black, 0, 0, width - 1, height - 1);
            }
            else
            {
                // Sets the images' size and position
                width =  Convert.ToInt32(buttonImage.Size.Width * scaleFactor);
                height = Convert.ToInt32(buttonImage.Size.Height * scaleFactor);
                var rect = new Rectangle(0, 0, width, height); 
                //// Draw the image
                g.DrawImage(buttonImage, rect);

                //// Draw with Gamma correction.
                //var rect = new Rectangle(0, 0, width, height);
                //var imageAttr = new System.Drawing.Imaging.ImageAttributes();
                //imageAttr.SetGamma(2.0F);
                //g.DrawImage(buttonImage, rect, 0, 0, width, height, GraphicsUnit.Pixel, imageAttr);
            }

            // No text ? then return
            if (string.IsNullOrEmpty(this.Text))
            {
                return;
            }

            // Set the text font and style and draw it.
            if (this.pressed && !this.ForeColorPressed.IsEmpty)
            {
                // Pressed color.
                textBrush = new SolidBrush(this.ForeColorPressed);
            }
            else
            {
                // Normal color.
                textBrush = new SolidBrush(this.ForeColor);
            }

            // Draw the text on TextPosition if specified.
            if (!this.TextPosition.IsEmpty)
            {
                float x = this.TextPosition.X * scaleFactor;
                float y = this.TextPosition.Y * scaleFactor;
                g.DrawString(this.Text, this.Font, textBrush, x, y);
            }
            else
            {
                // Otherwise use TextAlignment.
                width = Convert.ToInt32(this.Width * scaleFactor);
                height = Convert.ToInt32(this.Height * scaleFactor);
                var rectF = new RectangleF(0F, (height / 2) - (this.Font.Height / 2), width, height);
                var strFormat = new StringFormat();
                strFormat.Alignment = this.TextAlignment;
                g.DrawString(this.Text, this.Font, textBrush, rectF, strFormat);
            }
        }

        /// <summary>
        /// OnPaintBackground must not be called.
        /// </summary>
        /// <param name="pevent">
        /// The PaintEventArgs.
        /// </param>
        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
            //// don't call the base class
            ////base.OnPaintBackground(pevent);
        }
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900