Making a control transparent
Asked Answered
W

5

20

I am currently developing a simple image editing tool using Winforms and .NET 3.5 (work environment).

I have a requirement that when the user clicks a select tool button, a square (rectangle in C#) will appear that they can scale between 100x100 and 400x400. I have this bit fixed - the issue comes with making the background of the rectangle transparent.

I'm a little unclear on if transparency is supported in .NET 3.5, I've tried the following:

SetStyle(ControlStyles.SupportsTransparentBackColor, true);
pnlSelectArea.BackColor = Color.Transparent;
pnlSelectArea.ForeColor = Color.Transparent;
selectArea1.BackColor = Color.Transparent;
selectArea1.ForeColor = Color.Transparent;

But this has no effect - any advice would be appreciated.

Waggoner answered 20/2, 2012 at 9:7 Comment(3)
Check this #73494Esperance
Thanks for the help - I can't apply any of this to my solution but I appreciate the effort.Waggoner
You can find my simple approach explained in the post here:Villeinage
C
56

This is my special Control which contains an opacity property, it 100% works:

using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.Design;

public class TranspCtrl : Control
{
    public bool drag = false;
    public bool enab = false;
    private int m_opacity = 100;

    private int alpha;
    public TranspCtrl()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        SetStyle(ControlStyles.Opaque, true);
        this.BackColor = Color.Transparent;
    }

    public int Opacity
    {
        get
        {
            if (m_opacity > 100)
            {
                m_opacity = 100;
            }
            else if (m_opacity < 1)
            {
                m_opacity = 1;
            }
            return this.m_opacity;
        }
        set
        {
            this.m_opacity = value;
            if (this.Parent != null)
            {
                Parent.Invalidate(this.Bounds, true);
            }
        }
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle = cp.ExStyle | 0x20;
            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        Rectangle bounds = new Rectangle(0, 0, this.Width - 1, this.Height - 1);

        Color frmColor = this.Parent.BackColor;
        Brush bckColor = default(Brush);

        alpha = (m_opacity * 255) / 100;

        if (drag)
        {
            Color dragBckColor = default(Color);

            if (BackColor != Color.Transparent)
            {
                int Rb = BackColor.R * alpha / 255 + frmColor.R * (255 - alpha) / 255;
                int Gb = BackColor.G * alpha / 255 + frmColor.G * (255 - alpha) / 255;
                int Bb = BackColor.B * alpha / 255 + frmColor.B * (255 - alpha) / 255;
                dragBckColor = Color.FromArgb(Rb, Gb, Bb);
            }
            else
            {
                dragBckColor = frmColor;
            }

            alpha = 255;
            bckColor = new SolidBrush(Color.FromArgb(alpha, dragBckColor));
        }
        else
        {
            bckColor = new SolidBrush(Color.FromArgb(alpha, this.BackColor));
        }

        if (this.BackColor != Color.Transparent | drag)
        {
            g.FillRectangle(bckColor, bounds);
        }

        bckColor.Dispose();
        g.Dispose();
        base.OnPaint(e);
    }

    protected override void OnBackColorChanged(EventArgs e)
    {
        if (this.Parent != null)
        {
            Parent.Invalidate(this.Bounds, true);
        }
        base.OnBackColorChanged(e);
    }

    protected override void OnParentBackColorChanged(EventArgs e)
    {
        this.Invalidate();
        base.OnParentBackColorChanged(e);
    }
}
Convenance answered 20/2, 2012 at 10:31 Comment(10)
Worked nicely for me.Contraceptive
ppl just copy and paste in your custom class and change constructor name. works perfectly!! thank youRosettarosette
This currently has a serious bug. In the OnPaint override, it is calling Dispose on the e.Graphics object, which should not be done. The application is likely to crash if you dispose of the Graphics object that was passed in. If you didn't create it, you shouldn't dispose of it.Briar
Works nicely when "Control" was changed to "Panel".Lid
@Amen Ayach: The application will crash if i set SetStyle(ControlStyles.AllPaintingInWmPaint, true) to reduce flickerFleischman
How can i add TranspCtrl control on top of other controls. This control is always behind of other controlsFleischman
@Fleischman from designer right click it and click "Bring to Front", from code transpCtrl1.BringToFront();Convenance
@AmenAyach it works reliably only in designer. In runtime the transparent control keep redrawen by components that take some interaction, I did not find a way to keep it permanently on top.Godson
@AntonínLejsek I tried to put couple controls (TextBox, ComboBox and Button) above the Transparent one and I interacted with those controls and still working, note: I was using .Net 4.5.2 on windows 10, not sure if those "conditions" have effectsConvenance
Although this solution is good, its extremely silly to dispose of the graphics object, if you dont want system to paint you can simply remove the base.OnPaint(e) call from the code. no need to dispose graphics.Kiruna
G
3

You will need to use Opacity property and set it to zero to make form invisible.

If you want to make a control Transparent, as you have tried in your example, See this article

How to: Give Your Control a Transparent Background

It say the code you have written, must be in constructor of the control. Hence, I guess, you will need to create a custom control derived from your pnlSelectArea 's type most probaably a button. In in that custom control's constructor you can write code to set its style and color.

Goby answered 20/2, 2012 at 9:13 Comment(8)
I don't want to make the control invisible. I want to make its contents invisible so I can use it to mouse over different parts of the image and use it as a 'select tool'Waggoner
Then set those content's Opacity.Goby
Brother Mahepp no Opacity property in winforms just in WPFConvenance
It is available for Form in winforms as well. OP can use a borderless Form for his/her usage.Goby
@AmenAyach msdn.microsoft.com/en-us/library/…Goby
@Goby your link proove that no opacity for each "CONTROL" just for forms level...any way, thanks for your effort.Convenance
I think that you have not read my updated answer. What I have suggested for control is same which you later posted as your implementation.Goby
You should mention that this only exists for WPFHasa
W
1

Here is what worked for me with because the other solutions did not work.

This is with transparent UserControl added to ListView/TreeView Control Collection

I know it says ButtonRenderer but it should work for any controls.

In the UserControl:

protected override void OnPaint(PaintEventArgs e)
{
    ButtonRenderer.DrawParentBackground(e.Graphics, this.ClientRectangle, this);
}

in the Parent control:

protected override void WndProc(ref Message m) 
{
    if(m.Msg == 0xF)
        foreach(Control c in this.Controls) { c.Invalidate(); c.Update(); }

    base.WndProc(ref m);
}
Westernmost answered 15/12, 2015 at 2:28 Comment(0)
C
0

great!! I finally managed to draw transparent shapes. I've added a virtual method

Draw(g);

right before

bckColor.Dispose();
g.Dispose();
base.OnPaint(e);

and at the end the declaration of the virtual method

protected virtual void Draw(Graphics g){ }

Now I can continue creating my own Transparent shapes, graphics etc ...

Checani answered 13/10, 2015 at 13:14 Comment(1)
Have you ever putted your custom control on top of other controls?Fleischman
I
0

There is one simple workaround for this. You can create an image with a transparent background (PNG) and add it for the Image property of the icon. This works fine as information does not have much flexibility in styling. Sometime this might not be suitable for everyone. Remember this is only a workaround.

PS: Add where ever the text on the image and keep blank for the text property.

Implicit answered 11/4, 2020 at 19:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.