Click here to Skip to main content
11,433,800 members (59,843 online)
Click here to Skip to main content

Transparent UI for .NET and .NETCF

, 12 Jul 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
How to make your customized UI using transparent components?

Introduction

I have been trying for 2 weeks to find a code that can help me make a customized and really transparent user interface for my projects, but I did not find anything. Thus, I began programming in VS 2008. Here are my experiences to find a solution to make this happen!

Background

When you want to write a program with deceptive graphical user interface, you need some tools. One of its important tools is Graphical Form with pictorial Background.The second is Transparent components like Button and Labels.

See the instruction below!!!! Smile | :)

Using the Code

You can use this to define a graphical form with pictorial background.

public interface IControlBackground{
    Bitmap BackgroundImage { get; }
}
//
public class GForm : Form, IControlBackground
{
    Bitmap background;
    
    protected override void OnPaint(PaintEventArgs e)
    {
        if (background != null)
            e.Graphics.DrawImage(background, 0, 0);
        else
            base.OnPaint(e);
    }
    
    public Bitmap BackgroundImage
    {
        get 
        {
            return background; 
        }
        set
        {
            background = value;
        }
    }
}

IControlBackground uses as an interface between form and other components. which you can used in OnPaintBackground Event of these.

Now you can define other components such as Button and Label!

Here is the code!!!

public class ImageButton : System.Windows.Forms.Control
{
	/********************************************************
	 * Constants
	 *******************************************************/
	 
	/********************************************************
	 * Member Variables
	 *******************************************************/
	protected ButtonState state;
	protected Image image;
	protected Image disabledImage;
	protected Image overImage;
	protected Image pressedImage;
	protected DialogResult dialogResult;
	protected bool isDefault;
	protected Point textOffset = new Point(2,2);
               public    Control BackControl;
		
	#if !DESKTOP
	protected Font font;
	#endif

	/**************************************************************
	 * Designer Variables
	 *************************************************************/
	/// <summary> 
	/// Required designer variable.
	/// </summary>
	private System.ComponentModel.Container components = null;

	/********************************************************
	 * Constructor
	 *******************************************************/
	public ImageButton()
	{
		// This call is required by the Windows.Forms Form Designer.
		InitializeComponent();
		#if DESKTOP
			ResizeRedraw = true;
		#endif
	    #if !DESKTOP
		  font = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Regular);
	    #endif
	}

	/// <summary> 
	/// Clean up any resources being used.
	/// </summary>
	protected override void Dispose( bool disposing )
	{
		if( disposing )
		{
			if(components != null)
			{
				components.Dispose();
			}
		}
		base.Dispose( disposing );
	}

	#region Component Designer generated code
	/// <summary> 
	/// Required method for Designer support - do not modify 
	/// the contents of this method with the code editor.
	/// </summary>
	private void InitializeComponent()
	{
		components = new System.ComponentModel.Container();
		// 
		// ImageButton
		// 
		#if DESKTOP
		this.Name = "ImageButton";
		#endif
		this.Size = new System.Drawing.Size(32, 32);
	}
	#endregion

	/********************************************************
	 * Methods
	 *******************************************************/
	private bool InClient(int x, int y)
	{
		return ((x >= 0) && (x < ClientRectangle.Width) && 
			(y >= 0) && (y < ClientRectangle.Height));
	}
	
	/********************************************************
	 * Properties
	 *******************************************************/
	#if !DESKTOP
	new public Font Font
	{
		get
		{
			return font;
		}
		set
		{
			if (value == null) throw new ArgumentException();
			font = value;
		}
	}
	#endif

	public Image Image
	{
		get
		{
			return image;
		}
		set
		{
			if (image == value) return;
			image = value;
			if (state == ButtonState.Normal) Invalidate();
		}
	}

	public Image DisabledImage
	{
		get
		{
			return disabledImage;
		}
		set
		{
			if (disabledImage == value) return;
			disabledImage = value;
			if (state == ButtonState.Disabled) Invalidate();
		}
	}

	public Image OverImage
	{
		get
		{
			return overImage;
		}
		set
		{
			if (overImage == value) return;
			overImage = value;
			if (state == ButtonState.Over) Invalidate();
		}
	}

	public Image PressedImage
	{
		get
		{
			return pressedImage;
		}
		set
		{
			if (pressedImage == value) return;
			pressedImage = value;
			if (state == ButtonState.Pressed) Invalidate();
		}
	}
	
	#if DESKTOP
	[Browsable(true)]
	#endif
	[DefaultValue(null)]
	public override string Text
	{
		get
		{
			return base.Text;
		}
		set
		{
			base.Text = value;
		}
	}
	
	public Point TextOffset
	{
		get
		{
			return textOffset;
		}
		set
		{
			textOffset = value;
		}
	}
	
	public ButtonState ButtonState
	{
		get
		{
			return state;
		}
	}
	
	/********************************************************
	 * Overrides
	 *******************************************************/
	#if DESKTOP
	protected override void OnMouseEnter(EventArgs e)
	{
		state = ButtonState.Over;
		Invalidate();
		base.OnMouseEnter(e);
	}
	
	protected override void OnMouseLeave(EventArgs e)
	{
		state = ButtonState.Normal;
		Invalidate();
		base.OnMouseLeave(e);
	}
	#endif

	protected override void OnMouseDown(MouseEventArgs e) 
	{
		Capture = true; // Track
		state = ButtonState.Pressed;
		Invalidate();
		base.OnMouseDown(e);
	}

	protected override void OnMouseUp(MouseEventArgs e) 
	{
		Capture = false; // Release
		if (state != ButtonState.Disabled)
		{
			// The Pocket PC doesn't have an OnMouseLeave,
			// so the only option other then pressed is over.
			#if DESKTOP
				state = (InClient(MousePosition.X, MousePosition.Y) 
					? ButtonState.Over : ButtonState.Normal);
			#else
				state = ButtonState.Normal;
			#endif
			Invalidate();
		}
		base.OnMouseUp(e); // Base should only 'click' if mouse is in bounds...
	}

    protected override void OnMouseMove(MouseEventArgs e)
    {
        Capture = false; // Release
        if (state != ButtonState.Disabled)
        {
            #if DESKTOP
		state = (InClient(MousePosition.X, MousePosition.Y) 
			? ButtonState.Over : ButtonState.Normal);
            #else
                state = ButtonState.Over;
            #endif
            Invalidate();
        }
        base.OnMouseMove(e);
    }
    protected override void OnEnabledChanged( EventArgs e )
    {
	state = (Enabled ? ButtonState.Normal : ButtonState.Disabled);
	Invalidate();
	base.OnEnabledChanged(e);
    }

    protected override void OnTextChanged(EventArgs e)
    {
	// Redraw
	Invalidate();
	
	// Base
	base.OnTextChanged(e);
    }
    protected bool HasBackground = false;

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        IControlBackground form = this.Parent as IControlBackground;
        if (form == null)
        {
            base.OnPaintBackground(e);
            return;
        }
        else
        {
            HasBackground = true;
        }
        if (form.BackgroundImage!=null)
            e.Graphics.DrawImage(form.BackgroundImage,0,0,Bounds,GraphicsUnit.Pixel);
    }
        
    //protected override 
    //
         protected override void OnPaint(PaintEventArgs e)
	{
		// Use default image
        		doPaint(e.Graphics, state);
		// Create a solid brush using the foreground
		Brush TBrush = new SolidBrush(ForeColor);

		// If text is valid, draw it
		if ((base.Text != null) && (base.Text.Length > 0))
		{
			// Get the width of the string
			SizeF tSize = e.Graphics.MeasureString(base.Text, Font);
			
			// Get the location to draw
			Point DrawPoint = new Point((int)
			((ClientRectangle.Width - tSize.Width)/2),
			(int)((ClientRectangle.Height - tSize.Height)/2));

			// Offset Text?
			if (state == ButtonState.Pressed)
			{
				DrawPoint.X += textOffset.X;
				DrawPoint.Y += textOffset.Y;
			}
				
			// Draw the text using the solid brush and the current font
			e.Graphics.DrawString(base.Text, Font, TBrush, 
						DrawPoint.X, DrawPoint.Y);

			// Release the brush
			TBrush.Dispose();
		}
	}

    internal Color GetTransparentColor(Bitmap bm)
    {
        return bm.GetPixel(0, 0);
    }

    public void doPaint(Graphics gx,ButtonState bs)
    {
        ImageAttributes attrib = new ImageAttributes();
        Image im;
            
        im = this.Image;
        //
        if (bs == ButtonState.Pressed)
            im = this.PressedImage;
        else if (bs == ButtonState.Over)
            im = this.OverImage;
        //
        if (im != null)
        {
            Bitmap bm = new Bitmap(im);
            Color color = GetTransparentColor(bm);
            attrib.SetColorKey(color, color);
            //
            gx.DrawImage(bm, this.ClientRectangle, 0, 0, 
		this.ClientRectangle.Width, this.ClientRectangle.Height, 
		GraphicsUnit.Pixel, attrib);
        }
        else
            gx.Clear(BackColor);
    }

	#region IButtonControl Interface Implementation
	public DialogResult DialogResult
	{
		get
		{
			return dialogResult;
		}

		set
		{
			if(Enum.IsDefined(typeof(DialogResult), value))            
			{
				dialogResult = value;
			}
		}   
	}
        
	public void NotifyDefault(bool value)
	{
		if(isDefault != value)
		{
			isDefault = value;
		}
	}

	public void PerformClick()
	{
		if(Enabled)
		{
			OnClick(EventArgs.Empty);
		}
	}
	#endregion
} 

IMPORTANT!

Pixel 0,0 in Button Back Image is the transparency color! For better image processing, if you use PhotoShop, select the background transparent color the same as your form background image!

THE CODE IS SIMPLE! YOU WILL FIND IT HELPFUL!

History

  • Version 0.5- Fixed some bugs for painting background!

License

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

Share

About the Author

christ_A
CEO SyncDynaSys Inst.
Iran (Islamic Republic Of) Iran (Islamic Republic Of)
I studied in talented students high school and got a BSc degree on electrical eng. in aut.
I began programming when i was at 11 with gw-basic n
continued it with quick-basic, turbo-pascal, turbo c, and c++!
when i was at 18 i was an skilled programmer in turbo-pascal/c++. After 1995 i switched to RAD programming with Delphi 1.
Now i am an embedded system designer and programmer.
My int3r35T5:
<<< PHP/VC#/Symbian OS/Mobile Development/RTOS/uOS >>>

H066i35:
<<< Driving/Sport/................................ >>>

Comments and Discussions

 
Question??? Pin
XRage_25-Nov-09 2:49
memberXRage_25-Nov-09 2:49 
GeneralLooks a little too familiar Pin
Christian Resma Helle6-Oct-09 4:14
memberChristian Resma Helle6-Oct-09 4:14 
GeneralRe: Looks a little too familiar Pin
christ_A6-Oct-09 18:38
memberchrist_A6-Oct-09 18:38 
GeneralRe: Looks a little too familiar Pin
christ_A6-Oct-09 19:11
memberchrist_A6-Oct-09 19:11 
GeneralRe: Looks a little too familiar Pin
Christian Resma Helle6-Oct-09 22:00
memberChristian Resma Helle6-Oct-09 22:00 
GeneralRe: Looks a little too familiar Pin
christ_A6-Oct-09 22:16
memberchrist_A6-Oct-09 22:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150428.2 | Last Updated 12 Jul 2009
Article Copyright 2009 by christ_A
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid