Sunday, January 13, 2008

Transparent Controls in .NETCF

I work a lot with a graphic artist for developing solutions. The better the graphic artist you work with is, the harder it is to implement their designs to your application. One thing that my solutions have in common is that they all require transparent controls. My graphic artist loves having a image buttons on top of fancy background.

Here's some screen shots of what I've made with my graphic artist:

























In these screen shots I heavily use a transparent label control over a Form that has a background image. I normally set my controls to be designer visible so I can drag and drop while designing. Visual Studio 2005 and 2008 will automatically load all Custom Controls and UserControls

Implementing Transparent Controls

For creating transparent controls, I need the following:

1) IControlBackground interface - contains BackgroundImage { get; }
2) TransparentControlBase - draws the BackgroundImage of an IControlBackground form
3) Transparent Control - Inherits from TransparentControlBase
4) FormBase Form - implements IControlBackground and draws the background image to the form

Let's start off with the IControlBackground interface. Like I mentioned above, it only contains a property called BackgroundImage.

public interface IControlBackground
{
  Image BackgroundImage { get; }
}

Next we will need to create the TransparentControlBase. Let's create a class that inherits from Control. We then need to override the OnPaintBackground() event to draw the IControlBackground.BackgroundImage of the Parent control. To do this, we create an instance of IControlBackground from the Parent. Once we have the BackgroundImage, we draw part of the BackgroundImage where the transparent control is lying on.

We also override the OnTextChanged() and OnParentChanged() events to force a re-draw whenever the text or parent of the control is changed.

public class TransparentControlBase : Control
{
  protected bool HasBackground = false;

  protected override void OnPaintBackground(PaintEventArgs e)
  {
    IControlBackground form = Parent as IControlBackground;
    if (form == null) {
      base.OnPaintBackground(e);
      return;
    } else {
      HasBackground = true;
    }

    e.Graphics.DrawImage(
      form.BackgroundImage,
      0,
      0,
      Bounds,
      GraphicsUnit.Pixel);
  }

  protected override void OnTextChanged(EventArgs e)
  {
    base.OnTextChanged(e);
    Invalidate();
  }

  protected override void OnParentChanged(EventArgs e)
  {
    base.OnParentChanged(e);
    Invalidate();
  }
}

Now we need to create a control that inherits from TransparentControlBase. I'll create a simple TransparentLabel control for this example. The control will have the same behavior as the standard Label control, except that it can be transparent when used over a form or control that implements IControlBackground.

public class TransparentLabel : TransparentControlBase
{
  ContentAlignment alignment = ContentAlignment.TopLeft;
  StringFormat format = null;
  Bitmap off_screen = null;

  public TransparentLabel()
  {
    format = new StringFormat();
  }

  public ContentAlignment TextAlign
  {
    get { return alignment; }
    set
    {
      alignment = value;
      switch (alignment) {
        case ContentAlignment.TopCenter:
          format.Alignment = StringAlignment.Center;
          format.LineAlignment = StringAlignment.Center;
          break;
        case ContentAlignment.TopLeft:
          format.Alignment = StringAlignment.Near;
          format.LineAlignment = StringAlignment.Near;
          break;
        case ContentAlignment.TopRight:
          format.Alignment = StringAlignment.Far;
          format.LineAlignment = StringAlignment.Far;
          break;
      }
    }
  }

  protected override void OnPaint(PaintEventArgs e)
  {
    if (!base.HasBackground) {
      if (off_screen == null) {
        off_screen = new Bitmap(ClientSize.Width, ClientSize.Height);
      }
      using (Graphics g = Graphics.FromImage(off_screen)) {
        using (SolidBrush brush = new SolidBrush(Parent.BackColor)) {
          g.Clear(BackColor);
          g.FillRectangle(brush, ClientRectangle);
        }
      }
    } else {
      using (SolidBrush brush = new SolidBrush(ForeColor)) {
        e.Graphics.DrawString(
          Text,
          Font,
          brush,
          new Rectangle(0, 0, Width, Height),
          format);
      }
    }
  }
}

Now that we have our transparent controls, we need to create a Form that will contain these controls. First we need to create a base class that will implement IControlBackground and inherit from Form.

In this example, I added a background image to the solution and as an embedded resource. My default namespace is called TransparentSample and my background image is located at the root folder with the filename background.jpg

public class FormBase : Form, IControlBackground
{
  Bitmap background;

  public FormBase()
  {
    background = new Bitmap(
      Assembly.GetExecutingAssembly().GetManifestResourceStream(
      "TransparentSample.background.jpg"));
  }

  protected override void OnPaint(PaintEventArgs e)
  {
    e.Graphics.DrawImage(background, 0, 0);
  }

  public Image BackgroundImage
  {
    get { return background; }
  }
}

For the last step, we need to create a Form that will contain these transparent controls. To start, let's add a new Form to our project and let it inherit from FormBase instead of Form.

Now we can add our transparent controls to the main form.

public class MainForm : FormBase
{
  TransparentLabel label;

  public MainForm()
  {
    label = new TransparentLabel();
    label.Font = new Font("Arial", 16f, FontStyle.Bold);
    label.ForeColor = Color.White;
    label.Text = "Transparent Label";
    label.Bounds = new Rectangle(20, 60, 200, 50);
    Controls.Add(label);
  }
}

That wasn't very complicated, was it? Having a nice and intuitive UI offers a very good user experience. Being creative, imaginative, and learning to work with a graphic artist can really pay off.

81 comments:

  1. Exactly what i was looking for !
    Thank you.

    Is it possible to do the same thing with a picturebox ? How ?

    ReplyDelete
  2. I don't know, but don't work this example on my PDA (WinMobile5).

    ReplyDelete
  3. Works fine on PPC 2003, WM 5, and WM 6 for me.

    I can send you the Visual Studio solution to your email if you want to see how it looks in my projects.

    ReplyDelete
  4. Apparently there's a small bug in the TransparentControlBase() code, I overriden OnTextChanged() twice. Instead of overriding OnTextChanged() and OnParentChanged().

    Sorry about that. It's fixed now.

    ReplyDelete
  5. This is really cool and works good. I'm still pretty new in this area, but I can't get it to work, if I want to make a transparent control containing e.g. two transparent labels. The transparent labels in the transparent control doesn't seem to recognize the parent

    ReplyDelete
  6. Hi,

    I will test this with WM5, pleace send me ein VS sample juver@peru.com

    Tausend Thanks,

    Juver

    ReplyDelete
  7. Hi Christian,

    it is a very nice article! Does it work also on .Net compact framework 2.0SP2?

    Thanks Stephan

    ReplyDelete
  8. Great article. Exactly what I need. I'm trying to convert it over to vb and am having some problems. You wouldn't already have it in vb by chance?

    ReplyDelete
  9. A few people asked me about this before. I just never pulled myself together to port it to VB.

    If you manage to do it, I would really like to have a look at it :)

    ReplyDelete
  10. Hey man, thanks for this great code sample. It has helped me out ALOT. I had on problem though. I am creating an owner drawen list view and using you're class to make it's BG transparent. The issue is that when I interact with the listview it flickers. Usually you would just add a blank override for OnPaintBackground but I cannot do that in this case. Any suggestions? If you could email me at tjbishop -*@*- gmail dot com i would appreciate it. Tom

    ReplyDelete
  11. hi christian,
    Transparent label is really great,

    Based on your transparent label, I tried to create transparent panel and I want to place transparent label on top of it, transparent panel shows but I can able to see only white color on top of transparent label,

    Can you suggest what could be the problem?

    Here is source code for this:

    public interface IControlBackground
    {
    Image BackgroundImage { get; }
    }

    public class TransparentControlBase : Control
    {
    protected bool HasBackground = false;

    protected override void OnPaintBackground(PaintEventArgs e)
    {
    IControlBackground form = Parent as IControlBackground;
    if (form == null)
    {
    base.OnPaintBackground(e);
    return;
    }
    else
    {
    HasBackground = true;
    }

    e.Graphics.DrawImage(
    form.BackgroundImage,
    0,
    0,
    Bounds,
    GraphicsUnit.Pixel);
    }

    protected override void OnTextChanged(EventArgs e)
    {
    base.OnTextChanged(e);
    Invalidate();
    }

    protected override void OnParentChanged(EventArgs e)
    {
    base.OnParentChanged(e);
    Invalidate();
    }
    }
    public class TransparentPanelBase : Panel
    {
    protected bool HasBackground = false;

    protected override void OnPaintBackground(PaintEventArgs e)
    {
    IControlBackground form = Parent as IControlBackground;
    if (form == null)
    {
    base.OnPaintBackground(e);
    return;
    }
    else
    {
    HasBackground = true;
    }

    e.Graphics.DrawImage(
    form.BackgroundImage,
    0,
    0,
    Bounds,
    GraphicsUnit.Pixel);
    }

    protected override void OnTextChanged(EventArgs e)
    {
    base.OnTextChanged(e);
    Invalidate();
    }

    protected override void OnParentChanged(EventArgs e)
    {
    base.OnParentChanged(e);
    Invalidate();
    }
    }
    public class TransparentLabel : TransparentControlBase
    {
    ContentAlignment alignment = ContentAlignment.TopLeft;
    StringFormat format = null;
    Bitmap off_screen = null;

    public TransparentLabel()
    {
    format = new StringFormat();
    }

    public ContentAlignment TextAlign
    {
    get { return alignment; }
    set
    {
    alignment = value;
    switch (alignment)
    {
    case ContentAlignment.TopCenter:
    format.Alignment = StringAlignment.Center;
    format.LineAlignment = StringAlignment.Center;
    break;
    case ContentAlignment.TopLeft:
    format.Alignment = StringAlignment.Near;
    format.LineAlignment = StringAlignment.Near;
    break;
    case ContentAlignment.TopRight:
    format.Alignment = StringAlignment.Far;
    format.LineAlignment = StringAlignment.Far;
    break;
    }
    }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
    if (!base.HasBackground)
    {
    if (off_screen == null)
    {
    off_screen = new Bitmap(ClientSize.Width, ClientSize.Height);
    }
    using (Graphics g = Graphics.FromImage(off_screen))
    {
    using (SolidBrush brush = new SolidBrush(Parent.BackColor))
    {
    g.Clear(BackColor);
    g.FillRectangle(brush, ClientRectangle);
    }
    }
    }
    else
    {
    using (SolidBrush brush = new SolidBrush(ForeColor))
    {
    e.Graphics.DrawString(
    Text,
    Font,
    brush,
    new Rectangle(0, 0, Width, Height),
    format);
    }
    }
    }
    }
    public class TransparentPanel : TransparentPanelBase
    {
    Bitmap off_screen = null;
    protected override void OnPaint(PaintEventArgs e)
    {
    if (!base.HasBackground)
    {
    if (off_screen == null)
    {
    off_screen = new Bitmap(ClientSize.Width, ClientSize.Height);
    }
    using (Graphics g = Graphics.FromImage(off_screen))
    {
    using (SolidBrush brush = new SolidBrush(Parent.BackColor))
    {
    g.Clear(BackColor);
    g.FillRectangle(brush, ClientRectangle);
    }
    }
    }

    }
    }

    -venkateshcs

    ReplyDelete
  12. Overriding OnPaint and OnPaintBackground for the Panel control will only work in .NETCF 3.5. If you want to create a transparent panel in .NETCF 2.0 then inherit from ScrollableControl instead of Panel.

    ReplyDelete
  13. hey man.....
    its really gr8...
    but hav 1 query .. how to do it for listview control ???

    can u plz tell..

    ReplyDelete
  14. You can make your owner drawn list view inherit from TransparentControlBase instead of Control or ScrollableControl.

    When you add your owner drawn list view to a container that implements my IControlBackground it will draw part of the parent's backgorund image into the control.

    ReplyDelete
  15. Hello Christian!
    Thank you very much for this tutorial! That's exactly what I need.

    One question: How can I implement a "TransparentPictureBox"? I want to place a transparent PNG on a background image.

    public class TransparentPictureBox : TransparentControlBase {

    protected override void OnPaint(PaintEventArgs e) {
    // code?
    }

    }

    ReplyDelete
  16. Hey Manfred,

    You can use the SetColorKey() method of the ImageAttributes class to set your transparent color for drawing the image to your drawing surface.

    e.Graphics.DrawImage(.....)

    ReplyDelete
  17. hi,

    Im looking for transparent controls.In my application im having almost all controls.listview,label,textbox,datetime picker,combobox.Is this possible to get transparency for all the controls.If you guide in this regard it will be helpful for me. Will it affect the performance.because already in my application its taking time to load each form.

    ReplyDelete
  18. Christian, thank you very much for you fast reply! My TransparentPictureBox is working :-)

    ImageAttributes imageAttr = new ImageAttributes();
    imageAttr.SetColorKey(Color.White, Color.White);

    e.Graphics.DrawImage(
    image,
    new Rectangle(0, 0, Width, Height),
    0,
    0,
    Width,
    Height,
    GraphicsUnit.Pixel,
    imageAttr);

    ReplyDelete
  19. Hey Christian,

    I have a question regarding transparent control on transparent form...(I created both custom controls and they work)
    the problem is when I try to put the transparent picture box (transparency created with imageattributes) ober a form where I simply don't draw the background.

    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
    'MyBase.OnPaintBackground(e)
    End Sub

    The problem is that picture box is instead of part where transparency should occur showing the custom forms default backcolor(control color ; grey)

    Do you maybe know where is the problem?

    Thanks
    Grega

    ReplyDelete
  20. I want to have a picture box and a label both of which are transparent inside an usercontrol.
    I tried ur code but still the backcolor of the usercontrol comes?
    How do I fix that? If possible plz send me the sample code.

    ReplyDelete
  21. Hey guys, sorry for not replying immediately to your inquiries. I've been insanely busy these past few weeks.

    ReplyDelete

  22. I want to have a picture box and a label both of which are transparent inside an usercontrol.
    I tried ur code but still the backcolor of the usercontrol comes?
    How do I fix that? If possible plz send me the sample code.


    Does your UserControl implement the IControlBackground interface that exposes the background image to the child controls?

    If you haven't already did, you can download my visual studio solution from:
    http://cid-ca531e7fb4762c70.skydrive.live.com/self.aspx/Public/TransparentSample.zip

    If that doesn't help then send me your code and I'll look into it. Send it to christian.helle [at] yahoo dot com

    ReplyDelete

  23. Hey Christian,

    I have a question regarding transparent control on transparent form...(I created both custom controls and they work)
    the problem is when I try to put the transparent picture box (transparency created with imageattributes) ober a form where I simply don't draw the background.

    Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
    'MyBase.OnPaintBackground(e)
    End Sub

    The problem is that picture box is instead of part where transparency should occur showing the custom forms default backcolor(control color ; grey)

    Do you maybe know where is the problem?

    Thanks
    Grega


    Hey Grega,

    I don't think I completely understand. You can send me your code and full details of the problem and I'll find time to take a look at it.

    Send it to christian.helle [at] yahoo dot com

    ReplyDelete
  24. Hey Christian,

    Is it possible to have opacity? How?

    thanks.

    ReplyDelete
  25. By opacity, you mean setting a certain percentage of opacity for the transparent control?

    I guess if your control has a fixed background color, you could alpha blend that with the BackgroundImage of the parent.

    You could also do all sorts of image maniuplation or "pixel fu(k1n9" between the parent and child controls background.

    ReplyDelete
  26. Good code Christion, thak You.

    ReplyDelete
  27. Christian, Thank you for posting this!

    ReplyDelete
  28. The Link "http://cid-ca531e7fb4762c70.skydrive.live.com/self.aspx/Public/TransparentSample.zip" is not worked.
    Can you send the sample project code to my email:oraone@yeah.net?Thank you.

    ReplyDelete
  29. Hi,
    thanks very much for this tutorial.
    Your sample work like a charm on my WM6.
    Could you advise how can I change that code so the datagrid Background would be Transparent?
    Thanks in advance.

    ReplyDelete
  30. Hi Chris,

    really a good job!

    I try to put a TransparentPictureBox over a PictureBox or another TransparentPictureBox but and the lower picturebox becomes white. ¿Do you know why?

    A comment, Can you add all the comments and suggestions in one sample? TransparentSample only has label. I think put PictureBox, ListView, buttons and other controls all together can be very interesting.

    ReplyDelete
  31. many thx for this code and tutorial, but doesn't work for me. It compiles and doesn't run. I get an NullReferenceException at background= new Bitmap...in the FormBase.cs file.

    I also tried the zipped solution from the links above, but doesn't run too.

    Many thx in advance.

    ReplyDelete
  32. hi,
    this is great!

    but the transparent will fail, when the 2 label control are overlapping...

    ReplyDelete
  33. I am not able to do transparent picture box control, with the given above solution. Could you please post the code, to do transparent picture box control.

    ReplyDelete
  34. Currently I'm writing an article about Semi-Transparent controls, I am using a Transparent PictureBox control as a sample. It should be done any time now :)

    ReplyDelete
  35. I tried it out for a listview, but in vain, can u pls share ur code for the same.

    ReplyDelete
  36. this solution works fine if the screen resolution is 240x320, but if I want run the application on others resolutions (320x320 128 dpi, 480x640 192 dpi, etc) the background is displayed bad and the labels too...!!!
    if I want a standar application and I want not include backgrounds for all the resolutions, how do you solve this problem?

    Sorry for my english...!!!
    =(

    ReplyDelete
  37. The code I provided was not meant to be production quality code, I just meant to demonstrate how to do transparency in .NETCF

    But anyway, if you want support multiple resolutions you can either provide a background image that matches each screen resolution or stretch the background image

    ReplyDelete
  38. Hi,

    The code doesn't seem to be working for me.
    I am getting an 'NullException' at this part of the code
    ' background = new Bitmap(
    Assembly.GetExecutingAssembly().GetManifestResourceStream(
    "Transparent_test.blue1.bmp"));

    I have been trying real hard to get past this. Don't know what is wrong. Please help

    ReplyDelete
  39. Siri said...
    Hi,

    The code doesn't seem to be working for me.
    I am getting an 'NullException' at this part of the code
    ' background = new Bitmap(
    Assembly.GetExecutingAssembly().GetManifestResourceStream(
    "Transparent_test.blue1.bmp"));

    I have been trying real hard to get past this. Don't know what is wrong. Please help

    Hi,
    Just be sure your image is in the root folder of your application and then click on it to see properties and set Build Action to Embedded Ressource.

    ReplyDelete
  40. Try http://tinyurl.com/m3t4yv - it allows also custom drawing!

    ReplyDelete
  41. Christian-great looking app. im working in vb.net with CF1.1 Im trying to figure out how to have a fully transparent "clickable" item on top of my form. My background is literally a png of many buttons, and i want to place several transparent clickable items on top of the background. any ideas?

    ReplyDelete
  42. If you just need transparent clickable controls without any text or anything then you can just use the TransparentControlBase that I posted

    ReplyDelete
  43. Hi,

    Need to implement a transparent listview control, but having issues with how to create the custom list view control ? Checked the customlist view control from Microsoft and tried to use i but having issues.

    ReplyDelete
  44. Hi,
    I have downloaded your vb example and worked fine. I then added the files to my project. I inherited the FormBase to one of my Forms and when i tried to view the designer of my form i see a message displayed in the back that says "Visual Inheritance is currently disabled because the base class references a device-specific component or contains P/Invoke". I´m using the same files from your VB example (outside from my project worked fine) in my project. What am I doing wrong?

    ReplyDelete
  45. Hi Manrique,

    What you need is to create a design time attributes (xmta) file and enable DesktopCompatible and DesignTimeVisible on the UI components.

    Try looking into .NETCF design time attributes

    ReplyDelete
  46. Hi Christian,
    Thanks alot. Worked like a charm. Last question. I made a class for a transparent PictureBox. How can I implement the SizeMode property so the image can stretch?

    ReplyDelete
  47. Hi Manrique,

    You can redraw the image on to the surface. I have a how to post on resizing an image in .NETCF that you might find interesting...

    http://christian-helle.blogspot.com/2009/10/resizing-image-in-netcf.html

    ReplyDelete
  48. It works perfect. Thanks for your great article.

    ReplyDelete
  49. Hy Christian,

    the sample works great!

    So the transparency only works for controls direct above the forms-backgroundimage?Right?

    I have a picture box, where I draw a statusbar(like a volume char).
    And i have 2 buttons(or labels), one minus and one plus, if the user presses the minus button, status bar goes down, pressing the plus button the status bar grows up.
    That works fine, so far.

    But i want to place the 2 buttons directly on the picturebox(minus-button in the left, plus-button in the right), the buttons have to be transparent, so that the user don´t see them and thinks, he presses the statusbar itself.

    So is there a simple way to have transparent buttons(or labels) over a picturebox?

    Any clue?

    ReplyDelete
  50. Why not have the +/- drawn on one control and do hit tests on user clicks and redraw the image accordingly to simulate a +/- button press. Just an idea...

    ReplyDelete
  51. hi,
    Thanks for this great article.
    CAn you tell me if it's possible to create transparent forms ? if yes how ?
    Thanks.

    ReplyDelete
  52. That is possible indeed. You need to take a screenshot of the screen when the form loads, then override the OnPaint and OnPaintBackground for the form and paint the screendump using alphablending.

    ReplyDelete
  53. I have just tested that transparent labels are supported by calling the e.Graphics.DrawString method from OnPaint. E.g.:

    protected override void OnPaint(PaintEventArgs e){
    e.Graphics.DrawImage(BackgroundImage, 0, 0);
    e.Graphics.DrawString("Hello World!", ...);
    }

    ReplyDelete
  54. Its true that drawing directly using Graphics.DrawString will give a transparent effect but manually drawing all text using DrawString would be a tedious task

    ReplyDelete
  55. Hi i want to place a transperent label into panel of each form tat panels contains different colors but tat label is of white color background,, i need only the colored text of label to be displayed on every panel not the background.. can u suggest me with the code?
    i am using vb.net

    ReplyDelete
  56. First - I have to say this is great. I've been trying to get something like this to work on my own for a while but this works way better. Just thought since we're talking about transparency and some advanced graphics we should use some double buffering. Only a few things need to be added and it avoids the "flicker effect" if you are creating some sort of list that needs to be scrolled or a control that is moved or refreshed very often.

    Anyway, in the TransparentControlBase add

    protected Bitmap offScreenBmp = null;
    protected Graphics offScreenDC = null;
    private Size _lastSize = new Size(0, 0);

    Then in the OnPaintBackground override add some code that will check if the size of the control has changed - and if it has you regenerate the off screen graphics:

    protected override void OnPaintBackground(PaintEventArgs e)
    {
    if (this.Size != _lastSize)
    {
    offScreenBmp = new Bitmap(this.Width, this.Height);
    offScreenDC = Graphics.FromImage(offScreenBmp);
    }

    IControlBackground form = Parent as IControlBackground;
    if (form == null) {
    base.OnPaintBackground(e);
    return;
    } else {
    HasBackground = true;
    }
    // We redraw to the off screen graphics instead of the e.Graphics
    offScreenDC.DrawImage(
    form.BackgroundImage,
    0,
    0,
    Bounds,
    GraphicsUnit.Pixel);
    }

    The only other thing that needs to be done is to draw your string to the off screen graphics and then draw the entire off screen image to the label control. So inside the TransparentLabel OnPaint override you use this:

    using (SolidBrush brush = new SolidBrush(ForeColor))
    {
    base.offScreenDC.DrawString(
    Text,
    Font,
    brush,
    new Rectangle(0, 0, Width, Height),
    format);

    e.Graphics.DrawImage(base.offScreenBmp, 0, 0);
    }

    For Anyone that doesn't know - all this technique does is ensure that graphics are only drawn onto your label once per paint operation, instead of twice or more depending on what you're doing...

    Anyway - Chris can probably explain it better if he wants - I just thought this might help someoue out down the line...

    ReplyDelete
  57. Sorry - I forgot a line in the above post. The TransparentControlBase should actually have this in the OnPaintBackground override:

    if (this.Size != _lastSize)
    {
    offScreenBmp = new Bitmap(this.Width, this.Height);
    offScreenDC = Graphics.FromImage(offScreenBmp);
    _lastSize = this.Size;
    }

    The last line there will set the lastSize to the current size. You need this so a new Bitmap wont be created on every paint operation - or else you'll get an out of memory error real fast!

    ReplyDelete
  58. hi

    this is great stuff. Yhank you very much for sharing.

    I would like to ask how can we make those cool scrolling lists?
    now if the content of the form is larger than the screen, the standard windows scrollbar appears. how can we change into a more stylish one?
    to be able to scroll with finger-movements it is automatically built in in the win 6.5 OS, or it has to be programmed?

    thank you in advance.
    regards,
    Arnold

    ReplyDelete
  59. Can we have the SizeMode.StrechImage functionality for the transparent picture box, since i cannot resize the images everytime due to large no of images being used on form.

    Please do let me know the possible solutions.

    ReplyDelete
  60. great comment. thanks for sharing.

    ReplyDelete
  61. Hi,
    I am using Transparent controls created from here.

    I am having a Transparent Picture Box inside a Panel.
    Now on Form Load event when i set Panel's AutoScrollPosition, it does not have any effect.

    please do let me know the solution for this.

    ReplyDelete
  62. HERE IS A PORTABILITY TO VB.NET (PART 1)

    =======FORM BASE CLASS=========
    Imports System.Reflection

    Public Class FormBase
    Inherits Form
    Implements IControlBackground

    Dim background As Bitmap

    Public Sub New()
    background = New Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream("SmartDeviceProject1.EUflag_L.jpg"))
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    e.Graphics.DrawImage(background, 0, 0)
    End Sub

    Public Property BackgroundImage() As Image Implements IControlBackground.BackgroundImage
    Get
    Return background
    End Get
    Set(ByVal value As Image)

    End Set
    End Property
    End Class

    =============IControlBackground interface
    Public Interface IControlBackground
    Property BackgroundImage() As Image
    End Interface

    ==============TransparentControlBase class
    Public Class TransparentControlBase
    Inherits Control
    Protected HasBackground As Boolean = False

    Protected Overrides Sub OnPaintBackground(ByVal e As PaintEventArgs)
    Dim Form As IControlBackground = Parent 'as IControlBackground
    If Form Is Nothing Then
    MyBase.OnPaintBackground(e)
    Return
    Else
    HasBackground = True
    End If

    e.Graphics.DrawImage(Form.BackgroundImage, 0, 0, Bounds, GraphicsUnit.Pixel)
    End Sub

    Protected Overrides Sub OnTextChanged(ByVal e As EventArgs)
    MyBase.OnTextChanged(e)
    Invalidate()
    End Sub

    Protected Overrides Sub OnParentChanged(ByVal e As EventArgs)
    MyBase.OnParentChanged(e)
    Invalidate()
    End Sub
    End Class

    ReplyDelete
  63. (PART 2)

    =============TransparentLabel class
    Public Class TransparentLabel
    Inherits TransparentControlBase

    Dim alignment As ContentAlignment = ContentAlignment.TopLeft
    Dim format As StringFormat = Nothing
    Dim off_screen As Bitmap = Nothing

    Public Sub New()
    format = New StringFormat()
    End Sub

    Public Property TextAlign() As ContentAlignment
    Get
    Return alignment
    End Get
    Set(ByVal value As ContentAlignment)
    alignment = value
    Select Case alignment
    Case ContentAlignment.TopCenter
    format.Alignment = StringAlignment.Center
    format.LineAlignment = StringAlignment.Center
    Case ContentAlignment.TopLeft
    format.Alignment = StringAlignment.Near
    format.LineAlignment = StringAlignment.Near
    Case ContentAlignment.TopRight
    format.Alignment = StringAlignment.Far
    format.LineAlignment = StringAlignment.Far
    End Select
    End Set
    End Property


    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    If Not MyBase.HasBackground Then
    If off_screen Is Nothing Then
    off_screen = New Bitmap(ClientSize.Width, ClientSize.Height)
    End If
    Using g As Graphics = Graphics.FromImage(off_screen)
    Using brush As SolidBrush = New SolidBrush(Parent.BackColor)
    g.Clear(BackColor)
    g.FillRectangle(brush, ClientRectangle)
    End Using
    End Using
    Else
    Using brush As SolidBrush = New SolidBrush(ForeColor)
    e.Graphics.DrawString(Text, Font, brush, New Rectangle(0, 0, Width, Height), format)
    End Using
    End If
    End Sub
    End Class

    ========== USAGE
    Dim label As TransparentLabel

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim label As New TransparentLabel()
    label.Font = New Font("Arial", 16.0F, FontStyle.Bold)
    label.ForeColor = Color.White
    label.Text = "Transparent Label"
    label.Bounds = New Rectangle(20, 60, 200, 50)
    Controls.Add(label)
    End Sub

    ReplyDelete
  64. Is it possible draw a semitranparent elipse in front a picture box? how to?
    Tks!

    ReplyDelete
  65. Is it possible draw a semitranparent elipse in front a picture box? how to?
    Tks!

    ReplyDelete
  66. The sample works great. Anyone have code to make a transparent picturebox?

    ReplyDelete
  67. I used the ported code in vb.net and getting an error in the line,
    Dim Form As IControlBackground = Parent
    in OnPaintBackground in TransparentControlBase class. IT says 'InvalidCastException : When casting from a number, the value of the number must be less than infinity'.
    How to get rid of this error?
    Please guide me at the earliest.

    ReplyDelete
  68. Great opinion you public here. It would be great to find anything more concerning this topic. Thx you for giving that information. Ioan
    Kiev escort

    ReplyDelete
  69. I have a done all the instructions and procedure. but still cannot run it in my wm6? please help.and also i have a warning

    The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file:

    TransparentLabel --- The base class 'my.Mobile.Apps.TransparentControlBase' could not be loaded. Ensure the assembly has been referenced and that all projects have been built. 0 0

    ReplyDelete
  70. I have done all procedures and classes, but still it doesn't work in my wm6 and also i have a WARNING: The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file:

    TransparentLabel --- The base class 'EGIS.Mobile.Apps.TransparentControlBase' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.

    ReplyDelete
  71. You mentioned that you were writing an article using a transparent PictureBox as an example. Did you ever get to it. I'm having some throuble creating the beast.

    ReplyDelete
  72. This is one of the reliable and good post.Thanks for presenting this type of Information.This is one of the Important post.Your blog is playing a vital role In Internet marketing field.Android app developers

    ReplyDelete
  73. Hi
    is possible use as class library for use with basic4ppc?
    And How?
    Thanks

    ReplyDelete