Click here to Skip to main content
Click here to Skip to main content
Articles » Languages » C# » Windows Forms » Downloads
 
Add your own
alternative version

Non-transparent controls on a semi-transparent window

, 6 Jul 2006
The article describes the use and the principle of operation of semi-transparent controls with non-transparent child controls.
transparent_controls_demo.zip
TestSkinControl
App.ico
bin
Debug
KBSoft.Components.dll
TestSkinControl.exe
TestSkinControl.exe.manifest
TestSkinControl.csproj.user
transparent_controls_src.zip
Components
bin
components
common
components.csproj.user
skincomponents
///////////////////////////////////////////////////////////////////////////////
//
//  File:           skintextbox.cs
//
//  Facility:		The module contains the CaretState enumeration and the SkinTextbox class.
//
//  Abstract:       The control - text field with an arbitrary shape.
//
//  Environment:    VC 7.1
//
//  Author:         KB_Soft Group Ltd.
//
///////////////////////////////////////////////////////////////////////////////


using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using KBSoft.Components.Design;
using KBSoft.Components.Common;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Text;


namespace KBSoft.Components
{
	/// <summary>
	/// Enumeration - the caret visibility.
	/// </summary>
	enum CaretState{ Visible, Invisible };

	/// <summary>
	/// the class of the control - text field with an arbitrary shape.
	/// </summary>
	[ 
	ToolboxItem(true)
	]
	public class SkinTextbox : KBSoft.Components.SkinControl
	{
		#region Fields

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components = null;

		/// <summary>
		/// The field where the text is displayed.
		/// </summary>
		private Rectangle textRectangle;

		/// <summary>
		/// The displayed text.
		/// </summary>
		private String labelText = "";

		/// <summary>
		/// The filed indicates whether the caret should be displayed.
		/// </summary>
		private bool showCaret = true;

		/// <summary>
		/// The caret state.
		/// </summary>
		private CaretState caretState;

		/// <summary>
		/// The timer responsible for displaying the caret.
		/// </summary>
		private Timer caretTimer = null;

		/// <summary>
		/// The interval of displaying the caret.
		/// </summary>
		private int caretInterval = 300;

		/// <summary>
		/// the current position of the caret.
		/// </summary>
		private int caretPos = 0;
		/// <summary>
		/// the length of the caret.
		/// </summary>
		private int caretLength = 20;
		/// <summary>
		/// the pen that will draw the carret.
		/// </summary>
		private Pen caretPen;

		/// <summary>
		/// the font of the text that will be displayed in the textbox.
		/// </summary>
		private Font font = null;

		/// <summary>
		/// the pen that will draw the bounding rectangle in the design-time.		
		/// </summary>
		private Pen pen = null;

		/// <summary>
		/// The brush that will draw the text.
		/// </summary>
		private SolidBrush textBrush;
		
		/// <summary>
		/// The main control's image presenting its appearance.
		/// </summary>
		private Bitmap frontImage = null;
		
		#endregion

		#region Constructors

		/// <summary>
		/// The constructor that sets the default values for the fields.
		/// </summary>
		public SkinTextbox()
		{			
			InitializeComponent();

			caretState = CaretState.Visible;
			textRectangle = Utils.InflateRect( this.ClientRectangle, new Margins(-5,-5,-5,-5) );

			font = new Font( "CourierNew", 30 );
			pen = new Pen(Color.Green,3);
			pen.DashStyle = DashStyle.Dash;

			this.Paint +=new PaintEventHandler(SkinTextbox_Paint);
			this.caretTimer = new Timer();
			this.caretTimer.Interval = caretInterval;
			this.caretTimer.Tick +=new EventHandler(caretTimer_Tick);

			caretPen = new Pen( Color.FromArgb( 94,94,94 ), 3 );
			textBrush = new SolidBrush( caretPen.Color ); 

			this.caretTimer.Start();

			this.SizeChanged += new EventHandler(SkinTextbox_SizeChanged);
		}

		#endregion

		#region Properties

		/// <summary>
		/// Sets the caret position. If the position exceeds the string length, 
		/// the caret is set after the last character. If the set position is negative,
		/// the caret is set to the zero position.
		/// </summary>
		public int CaretPos
		{
			get{ return caretPos;  }
			set
			{
				if( value > labelText.Length || value < 0 ) 
					return;

				caretPos = value; 
				Invalidate();
			}
		}

		/// <summary>
		/// The image presenting appearance of the control.
		/// Fills the whole area of the control.
		/// </summary>
		public Bitmap FromntImage
		{
			get{ return this.frontImage;  }
			set{ this.frontImage = value; }
		}

		/// <summary>
		/// the property sets the timer interval that regulates the caret displaying.
		/// </summary>
		public int CaretInterval
		{
			get{ return caretInterval;}
			set
			{
				this.caretTimer.Stop();
				this.caretTimer.Interval = value;
				this.caretTimer.Start();
			}
		}


		/// <summary>
		/// the property sets the text string that is displayed in the textbox.
		/// After the string is set, the caret is displayed in the end of the string.
		/// </summary>
		public String LabelText
		{
			get{ return this.labelText; }
			set
			{ 
				if( value == null )
					return;

				this.labelText = value;
				this.CaretPos = labelText.Length;

				Invalidate();
				Update();
			}
		}

		/// <summary>
		/// The property regulates the caret displaying.
		/// </summary>
		public bool ShowCaret
		{
			get{ return this.showCaret;}
			set
			{
				if( value == showCaret )
					return;

				if( !value )
					this.caretTimer.Stop();
				else
					this.caretTimer.Start();

				showCaret = value;
			}
		}

		/// <summary>
		/// the property sets the rectangle, where the text will be displayed.
		/// </summary>
		public Rectangle TextRectangle
		{
			get{ return this.textRectangle;  }
			set
			{ 
				this.textRectangle = value; 
				Invalidate();
			}
		}

		/// <summary>
		/// The property sets the textbox font.
		/// </summary>
		public Font TextFont
		{
			get{ return this.font;  }
			set
			{ 
				this.font = value;

				Invalidate();
				Update();
			}
		}

		/// <summary>
		/// the property sets the color, with the help of which the caret will be displayed.
		/// </summary>
		public Color CaretColor
		{
			get{ return this.caretPen.Color;  }
			set
			{ 
				this.caretPen.Color = value; 

				Invalidate();
				Update();
			}
		}

		/// <summary>
		/// The property sets the width of the caret.
		/// </summary>
		public int CaretWidth
		{
			get{ return (int)this.caretPen.Width;  }
			set
			{ 
				this.caretPen.Width = (float)value; 

				Invalidate();
				Update();
			}
		}

		/// <summary>
		/// The property sets the length of the caret.
		/// </summary>
		public int CaretLength
		{
			get{ return this.caretLength;  }
			set
			{ 
				this.caretLength = value; 
				Invalidate();
				Update();
			}
		}

		/// <summary>
		///the property sets the color of the text in the textbox.
		/// </summary>
		public Color TextColor
		{
			get{ return this.textBrush.Color;  }
			set
			{ 
				this.textBrush.Color = value; 

				Invalidate();
				Update();
			}
		}

		#endregion

		#region Methods

		/// <summary>
		/// freeing the used resources.
		/// </summary>
		/// <param name="disposing">the parameter is set true if the Dispose() function was called, 
		/// and is set false if the function is called during the finalizing.</param>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if( components != null) 
				{
					components.Dispose();
				}

				
				this.frontImage.Dispose();
			}
			base.Dispose( disposing );
		}

		#region 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();
		}
		
		#endregion

		/// <summary>
		/// drawing the control.
		/// </summary>
		/// <param name="sender">the object invoked the event.</param>
		/// <param name="e">the event's parameters</param>
		private void SkinTextbox_Paint( object sender, PaintEventArgs e )
		{
			e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
			e.Graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

			if( this.frontImage != null )
				e.Graphics.DrawImage( this.frontImage, 0, 0 );

			
			StringFormat sfmt = new StringFormat();
			sfmt.Alignment = StringAlignment.Near;
			sfmt.LineAlignment = StringAlignment.Center;

			e.Graphics.DrawString( this.LabelText, font, textBrush , this.textRectangle, sfmt );

			if( this.DesignMode )
			{
				e.Graphics.DrawRectangle( pen, this.textRectangle );
			}
	
			String dop = labelText.Substring( 0, caretPos );
			

			SizeF size = e.Graphics.MeasureString( dop, font );
			int xPos = textRectangle.X + (int)size.Width - 7;
			int yPos = textRectangle.Y + textRectangle.Height/2 + font.Height/2 - 7;

			if( caretPos == 0 )
				xPos += 15;

			caretPen.StartCap = LineCap.Round;
			caretPen.EndCap = LineCap.Round;

			if( this.caretState == CaretState.Visible && this.ShowCaret )
				e.Graphics.DrawLine( caretPen , xPos, yPos, xPos + caretLength,yPos );

		}



		/// <summary>
		/// The function adds the character to an arbitrary position of the string.
		/// </summary>
		/// <param name="ch">the character to be added.</param>
		/// <param name="pos">the position where the character should be added.</param>
		public void AddSymbol( Char ch, int pos )
		{
			StringBuilder sb = new StringBuilder(this.labelText);
			sb.Insert(pos, ch);

			this.labelText = sb.ToString();
			Invalidate();
		}

		/// <summary>
		/// The functions deletes the character from the arbitrary position.
		/// </summary>
		/// <param name="pos">the position where the character should be deleted.</param>
		/// <param name="count">a number of characters to be deleted.</param>
		public void DeleteSymbol( int pos, int count )
		{
			this.labelText = this.labelText.Remove( pos,count );
			
			Invalidate();
		}

		/// <summary>
		/// The function adds the character to the current caret position shifting the caret to the right.
		/// Allows characters to be always added to the last position by default.
		/// </summary>
		/// <param name="ch">the character to be added.</param>
		public void AddSymbol(char ch)
		{
			AddSymbol( ch,this.caretPos );
			this.CaretPos++;
		}

		/// <summary>
		/// the function deletes the character from the current caret position shifting the caret to the left.
		/// </summary>
		public void DeleteSymbol()
		{
			if( this.LabelText == "" || this.CaretPos == 0 )
				return;

			DeleteSymbol( this.CaretPos-1,1 );
			CaretPos--;
		}

		/// <summary>
		/// the function that reacts on the timer. It hides or displays the caret.
		/// </summary>
		/// <param name="sender">the object invoked the event.</param>
		/// <param name="e">the event's parameters.</param>
		private void caretTimer_Tick( object sender, EventArgs e )
		{
			if( this.caretState == CaretState.Invisible )
				caretState = CaretState.Visible;
			else
				caretState = CaretState.Invisible;

			Invalidate();
		}

		/// <summary>
		/// the function that handles displaying the rectangle bounding the text 
		/// in the design-time.
		/// </summary>
		/// <param name="sender">The object invoked the event.</param>
		/// <param name="e">the event parameters.</param>
		private void SkinTextbox_SizeChanged( object sender, EventArgs e )
		{
			if( DesignMode )
			{
				this.textRectangle = Utils.InflateRect( 
					new Rectangle( 0,0, this.Width, this.Height ) , 
					new Margins (-7,-8,-7,-7) );

				Invalidate();
			}
		}

		#endregion
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Alexandr Golovanov
Web Developer
Russian Federation Russian Federation
Alexandr Golovanov is a .NET developer at KB_Soft Group, an offshore software development company located in Russia, Novosibirsk. Here he has worked
on various .NET projects.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150414.1 | Last Updated 6 Jul 2006
Article Copyright 2006 by Alexandr Golovanov
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid