Clear background of transparent user control

2019-07-21 11:19发布

问题:

I'm working on ImageButton, in which I paint every state(i've got several images for each state) of this button (like mouseOver, mouseDown etc.).

I've made control transparent using this code:

public ImageButton()
{
  InitializeComponent();

  this.SetStyle(ControlStyles.Opaque, true);
  this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
}

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

But there's a problem, after few switches of state, corners becoming sharp and ugly, to solve this problem I need to clear background, but if my control is transparent then it's impossible.

I've tried this solution: Clearing the graphics of a transparent panel C# but it's slow and makes control flickering.

Do you have any ideas how to clear this background and keep transparency of control?

回答1:

Ok, I've solved this problem. I've worked around it by setting control as not transparent and I draw canvas which is under my control, as background of my ImageButton.

Solution (in Paint event):

//gets position of button and transforms it to point on whole screen
//(because in next step we'll get screenshot of whole window [with borders etc])
Point btnpos = this.Parent.PointToScreen(new Point(Location.X, Location.Y));

//now our point will be relative to the edges of form  
//[including borders, which we'll have on our bitmap]
if (this.Parent is Form)
{
      btnpos.X -= this.Parent.Left;
      btnpos.Y -= this.Parent.Top;
}
else
{
    btnpos.X = this.Left;
    btnpos.Y = this.Top;
}

//gets screenshot of whole form
Bitmap b = new Bitmap(this.Parent.Width, this.Parent.Height);
this.Parent.DrawToBitmap(b, new Rectangle(new Point(0, 0), this.Parent.Size));

//draws background (which simulates transparency)
e.Graphics.DrawImage(b,
                new Rectangle(new Point(0, 0), this.Size),
                new Rectangle(btnpos, this.Size),
                GraphicsUnit.Pixel);

//do whatever you want to draw your stuff

PS. It doesn't work in designtime.