Click here to Skip to main content
15,886,362 members
Articles / Desktop Programming / Windows Forms

Shape Control for .NET

Rate me:
Please Sign up or sign in to vote.
4.84/5 (170 votes)
23 Mar 2017CPOL10 min read 379.4K   21.6K   301  
Implementing shape control that supports transparency, custom design-time editors and simple animation
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Design
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
Imports System.Drawing.Drawing2D


Friend Class ShapeTypeEditorControl
	Inherits System.Windows.Forms.UserControl
	' Stores the shape
	Public shape As ShapeType
	' Specification for the UI

	'number of shapes
	'number of rows
	'number of columns
	'width of each shape
	Private _numshape As Integer, _numrow As Integer, _numcol As Integer, _valid_width As Integer, _valid_height As Integer, _width As Integer = 20, _
		_height As Integer = 20
	'height of each shape

	Public Sub New(initial_shape As ShapeType)
		Me.shape = initial_shape
		'Find the number of shapes in the enumeration
		Dim numshape As Integer = [Enum].GetValues(GetType(ShapeType)).GetLength(0)

		'Find the number of rows and colums to accomodate the shapes
		Dim numcol As Integer = 0, numrow As Integer = 0
		numrow = CInt(Math.Truncate(Math.Sqrt(numshape)))
		numcol = numshape \ numrow
		If numshape Mod numcol > 0 Then
			numcol += 1
		End If

		'Record the specifications
		_numshape = numshape
		_numrow = numrow
		_numcol = numcol

		_valid_width = _numcol * _width + (_numcol - 1) * 6 + 2 * 4
		_valid_height = _numrow * _height + (_numrow - 1) * 6 + 2 * 4
	End Sub

	Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
		Dim bm As New Bitmap(Me.Width, Me.Height, e.Graphics)
		Dim g As Graphics = Graphics.FromImage(bm)
		g.FillRectangle(Brushes.LightGray, New Rectangle(0, 0, bm.Width, bm.Height))
		e.Graphics.FillRectangle(Brushes.LightGray, New Rectangle(0, 0, Me.Width, Me.Height))
		Dim x As Integer = 4, y As Integer = 4
		Dim n As Integer = 0
		For Each shape As ShapeType In [Enum].GetValues(GetType(ShapeType))

			Dim path As New GraphicsPath()
			CustomControl1.updateOutline(path, shape, _width, _height, 2)
			g.FillRectangle(Brushes.LightGray, 0, 0, bm.Width, bm.Height)
			g.FillPath(Brushes.Yellow, path)
			g.DrawPath(Pens.Red, path)
			e.Graphics.DrawImage(bm, x, y, New Rectangle(New Point(0, 0), New Size(_width + 1, _height + 1)), GraphicsUnit.Pixel)
			If Me.shape.Equals(shape) Then
				e.Graphics.DrawRectangle(Pens.Red, New Rectangle(New Point(x - 2, y - 2), New Size(_width + 4, _height + 4)))
			End If
			n += 1
			x = (n Mod _numcol) * (_width)
			x = x + (n Mod _numcol) * 6 + 4
			y = (n \ _numcol) * (_height)

			y = y + (n \ _numcol) * 6 + 4
		Next
	End Sub

	Private Sub InitializeComponent()
		' 
		' ShapeTypeEditorControl
		' 
		Me.BackColor = System.Drawing.Color.LightGray
		Me.Name = "ShapeTypeEditorControl"

	End Sub

	Protected Overrides Sub OnMouseDown(e As System.Windows.Forms.MouseEventArgs)

		If e.Button.Equals(MouseButtons.Left) Then
			If e.X > _valid_width Then
				Return
			End If
			If e.Y > _valid_height Then
				Return
			End If

			Dim x As Integer, y As Integer
			Dim n As Integer
			x = e.X
			y = e.Y
			n = (y \ (_valid_height \ _numrow)) * _numcol + ((x \ (_valid_width \ _numcol)) Mod _numcol)

			Dim count As Integer = 0

			For Each shape As ShapeType In [Enum].GetValues(GetType(ShapeType))
				If count = n Then
					Me.shape = shape
					'close the editor immediately
					SendKeys.Send("{ENTER}")
				End If
				count += 1
			Next
		End If

	End Sub

End Class




Public Class ShapeTypeEditor
	Inherits System.Drawing.Design.UITypeEditor
	Public Sub New()
	End Sub

	' Indicates whether the UITypeEditor provides a form-based (modal) dialog, 
	' drop down dialog, or no UI outside of the properties window.
	<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name := "FullTrust")> _
	Public Overrides Function GetEditStyle(context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
		Return UITypeEditorEditStyle.DropDown
	End Function

	' Displays the UI for value selection.
	<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name := "FullTrust")> _
	Public Overrides Function EditValue(context As System.ComponentModel.ITypeDescriptorContext, provider As System.IServiceProvider, value As Object) As Object
		' Return the value if the value is not of type ShapeType
		If value.[GetType]() IsNot GetType(ShapeType) Then
			Return value
		End If

		' Uses the IWindowsFormsEditorService to display a 
		' drop-down UI in the Properties window.
		Dim edSvc As IWindowsFormsEditorService = DirectCast(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
		If edSvc IsNot Nothing Then
			' Display an Shape Type Editor Control and retrieve the value.
			Dim editor As New ShapeTypeEditorControl(CType(value, ShapeType))
			edSvc.DropDownControl(editor)

			' Return the value in the appropraite data format.
			If value.[GetType]() Is GetType(ShapeType) Then
				Return editor.shape
			End If
		End If
		Return value
	End Function

	' Draws a representation of the property's value.
	<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name := "FullTrust")> _
	Public Overrides Sub PaintValue(e As System.Drawing.Design.PaintValueEventArgs)
		Dim bm As New Bitmap(e.Bounds.Width + 4, e.Bounds.Height + 4, e.Graphics)
		Dim g As Graphics = Graphics.FromImage(bm)
		Dim shape As ShapeType = CType(e.Value, ShapeType)
		Dim path As New GraphicsPath()

		CustomControl1.updateOutline(path, shape, e.Bounds.Width - 5, e.Bounds.Height - 5, 2)
		g.FillPath(Brushes.Yellow, path)
		g.DrawPath(Pens.Red, path)
		e.Graphics.DrawImage(bm, 3, 3, New Rectangle(New Point(0, 0), New Size(e.Bounds.Width, e.Bounds.Height)), GraphicsUnit.Pixel)

	End Sub

	' Indicates whether the UITypeEditor supports painting a 
	' representation of a property's value.
	<System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name := "FullTrust")> _
	Public Overrides Function GetPaintValueSupported(context As System.ComponentModel.ITypeDescriptorContext) As Boolean
		Return True
	End Function
End Class



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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Singapore Singapore
Coder. Hacker. Fixer.

Comments and Discussions