65.9K
CodeProject 正在变化。 阅读更多。
Home

适用于 .NET 和 .NETCF 的透明 UI

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (2投票s)

2009年7月12日

CPOL

1分钟阅读

viewsIcon

34536

downloadIcon

2688

如何使用透明组件制作您自定义的 UI?

引言

我一直在尝试两周,想找到一段代码,它可以帮助我为我的项目创建一个定制的、真正透明的用户界面,但我什么也没找到。 因此,我开始在 VS 2008 中编程。以下是我的经验,希望能找到一个解决方案来实现它!

背景

当你想要编写一个具有欺骗性图形用户界面的程序时,你需要一些工具。 其中一个重要的工具是具有图片背景的图形表单。第二个是透明组件,例如按钮和标签。

请看下面的说明!!!! :-)

Using the Code

你可以使用它来定义一个具有图片背景的图形表单。

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 用作表单和其他组件之间的接口,你可以在这些组件的 OnPaintBackground 事件中使用它。

现在你可以定义其他组件,例如 ButtonLabel

这是代码!!!

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
} 

重要提示!

按钮背景图像中的像素 0,0 是透明颜色! 为了获得更好的图像处理效果,如果你使用 PhotoShop,请选择与你的表单背景图像相同的背景透明颜色!

代码很简单! 你会发现它很有帮助!

历史

  • 版本 0.5 - 修复了一些用于绘制背景的错误!
© . All rights reserved.