Home > Software engineering >  Removing the button's background?
Removing the button's background?

Time:01-25

Based on my previous question (enter image description here

I wish it to have transparent background, i.e. to not draw the gray border on top of the black background.

Can I do it with my TransparentButton class, without major changes (like drawing the text and background, and border manually)?

CodePudding user response:

Why are you setting WS_EX_TRANSPARENT in CreateParams? When I need a transparent background, I don't use WinAPI constants. WinForms was created to simplify the usage, and the solution I know is to set the BackgroundColor of your button to Color.Transparent.

Yes, it just sets the background color same as the parent's background color, but it works.

CodePudding user response:

This edited TransparentButton improves on my previous answer. It no longer requires an override to OnPaint and uses no custom drawing whatsoever. What I missed the first time is to simply set the Button.BackgroundImage to the camouflage bitmap.

runtime

Requirements:

  • Create a button with transparent background.
  • Do it without drawing the background manually in OnPaint.
  • Keep the Button.FlatStyle as FlatStyle.Standard.
  • Do not disturb the rounded edges of the standard button.

class TransparentButton : Button
{
    protected override void OnSizeChanged(EventArgs e)
    {
        base.OnSizeChanged(e);
        Refresh();
    }
    public void SetParentForm(Form form)
    {
        _parentForm= form;
        Refresh();
    }
    Form? _parentForm = null;
    public new void Refresh()
    {
        if (!(DesignMode || _parentForm == null))
        {
            // Hide this button before drawing
            Visible = false;

            // Draw the full container
            var tmp = (Bitmap)new Bitmap(_parentForm.Width, _parentForm.Height);
            _parentForm.DrawToBitmap(tmp, new Rectangle(0, 0, _parentForm.Width, _parentForm.Height));
            var ptScreen = _parentForm.PointToScreen(_parentForm.ClientRectangle.Location);
            var ptOffset = new Point(
                ptScreen.X - _parentForm.Location.X,
                ptScreen.Y - _parentForm.Location.Y);

            var clipBounds = new Rectangle(Location.X   ptOffset.X, Location.Y   ptOffset.Y, Width, Height);
            BackgroundImage = tmp.Clone(
                clipBounds, 
                System.Drawing.Imaging.PixelFormat.DontCare);

            // Show this button.
            Visible = true;
        }
    }

Design Mode Example

Main form BackgroundImage to main form with a Stretch layout. Then overlay a TableLayoutPanel whose job it is to keep the button scaled correctly as the form resizes. TransparentButton is now placed in one of the cells.

designer


Test

Here's the code I used to test this answer:

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();       
    protected override void onl oad(EventArgs e)
    {
        base.OnLoad(e);
        buttonTransparent.FlatStyle= FlatStyle.Standard;
        buttonTransparent.SetParentForm(this);
        buttonTransparent.ForeColor= Color.White;
        buttonTransparent.Click  = onClickTransparent;
    }
    private void onClickTransparent(object? sender, EventArgs e) =>
        MessageBox.Show("Clicked!");
    protected override CreateParams CreateParams
    {
        get
        {
            const int WS_EX_COMPOSITED = 0x02000000;
            // https://stackoverflow.com/a/36352503/5438626
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= WS_EX_COMPOSITED;
            return cp;
        }
    }
}
  • Related