(c) 2003 Visual Studio Magazine 
Fawcette Technical Publications

VB.NET	Create a Combo Box Column
Listing 1	You can make a DataGrid column show and hide a combo box, instead of the classic text box, by deriving from the DataGridTextBoxColumn class to manage events such as Edit and Leave.

Public Class DataGridComboBoxColumn
	Inherits DataGridTextBoxColumn

	Public MyCombo As ComboBox

	Public Sub New()
		MyBase.New()

		MyCombo = New ComboBox
		AddHandler MyCombo.Leave, New EventHandler( _
			AddressOf LeaveComboBox)

	End Sub

	Protected Overloads Overrides Sub Edit(ByVal _
		source As CurrencyManager, ByVal rowNum _
		As Integer, ByVal bounds As Rectangle, _
		ByVal readOnly1 As Boolean, ByVal _
		instantText As String, ByVal cellIsVisible As Boolean)
		MyBase.Edit(source, rowNum, bounds, _
			readOnly1, instantText, cellIsVisible)

		MyCombo.Parent = Me.TextBox.Parent
		MyCombo.Location = Me.TextBox.Location
		MyCombo.Size = New Size(Me.TextBox.Size.Width, _
			MyCombo.Size.Height)
		MyCombo.Text = Me.TextBox.Text
		Me.TextBox.Visible = False
		MyCombo.Visible = True
		MyCombo.BringToFront()
		MyCombo.Focus()

	End Sub

	Private Sub LeaveComboBox(ByVal sender _
		As Object, ByVal e As EventArgs)
		MyCombo.Hide()
	End Sub
End Class

VB.NET	Commit User Changes
Listing 2	This DataGrid combo box column implementation commits changes the user enters through the combo box to the data source.

Public Class DataGridComboBoxColumn
	Inherits DataGridTextBoxColumn

	Public MyCombo As DataGridComboBox
	Private m_isEditing As Boolean

	Public Sub New()
		MyBase.New()

		MyCombo = New DataGridComboBox
		m_isEditing = False

		AddHandler MyCombo.Leave, New _
			EventHandler(AddressOf LeaveComboBox)
		AddHandler MyCombo.SelectionChangeCommitted, New _
			EventHandler(AddressOf OnSelectionChangeCommitted)
	End Sub

	Protected Overloads Overrides Sub Edit(ByVal source As _
		CurrencyManager, ByVal rowNum As Integer, ByVal _
		bounds As Rectangle, ByVal readOnly1 As Boolean, _
		ByVal instantText As String, ByVal cellIsVisible As _
		Boolean)
		MyBase.Edit(source, rowNum, bounds, _
			readOnly1, instantText, cellIsVisible)

		MyCombo.Parent = Me.TextBox.Parent
		MyCombo.Location = Me.TextBox.Location
		MyCombo.Size = New Size(Me.TextBox.Size.Width, _
			MyCombo.Size.Height)
		MyCombo.Text = Me.TextBox.Text
		Me.TextBox.Visible = False
		MyCombo.Visible = True
		MyCombo.BringToFront()
		MyCombo.Focus()

	End Sub

	Private Sub LeaveComboBox(ByVal sender As _
		Object, ByVal e As EventArgs)
		MyCombo.Hide()
	End Sub

	Protected Overloads Overrides Function Commit(ByVal _
		dataSource As CurrencyManager, ByVal rowNum As _
		Integer) As Boolean

		If m_isEditing Then
			m_isEditing = False
			SetColumnValueAtRow(dataSource, rowNum, _
				MyCombo.Text)
		End If
		Return True

	End Function
	Private Sub OnSelectionChangeCommitted(ByVal sender As _
		Object, ByVal e As EventArgs)

		m_isEditing = True
	MyBase.ColumnStartedEditing(sender)

	End Sub
End Class

VB.NET	Color a DataGrid Cell
Listing 3	You can customize a DataGrid cell's look by overriding the Paint event to change the values of the cell's background and foreground colors.

Public Class DataGridColoredTextBoxColumn
	Inherits DataGridTextBoxColumn

	Public Sub New(ByVal prop As PropertyDescriptor, _
		ByVal format As String, ByVal isDefault As Boolean)
		MyBase.New(prop, format, isDefault)
	End Sub

	Protected Overloads Overrides Sub Paint(ByVal g As _
		Graphics, ByVal bounds As Rectangle, ByVal source As _
		CurrencyManager, ByVal rowNum As Integer, ByVal _
		backBrush As Brush, ByVal foreBrush As Brush, ByVal _
		alignToRight As Boolean)

		Dim obj As Object

		Try
			obj = Me.GetColumnValueAtRow(source, rowNum)
			If (Not (obj) Is Nothing) Then
				Dim i As Integer
				i = CType(obj, Integer)
				If i < 0 Then
					backBrush = New SolidBrush(Color.Red)
					foreBrush = New SolidBrush(Color.White)
				End If
			End If

		Catch ex As Exception

		Finally
			MyBase.Paint(g, bounds, source, rowNum, backBrush, _
				foreBrush, alignToRight)
		End Try
	End Sub
End Class

C#	Make a Singleton App
Listing 4	The named Mutex serves as a simple cross-process communication mechanism when you use the SingletonApp class to implement a singleton application. If the named Mutex is unowned, SingletonApp launches the app. Otherwise, it simply returns, causing the application to terminate because no window is pumping messages, and the Main method returns.

public class SingletonApp 
{
	static Mutex m_Mutex;
	public static void Run(Form mainForm)
	{
		if(IsFirstInstance())
		{
			Application.ApplicationExit += new 
				EventHandler(OnExit);
			Application.Run(mainForm);
		}
	}
	//Other versions of Run()
	static bool IsFirstInstance()
	{
		m_Mutex = new Mutex(false,"SingletonApp Mutex");

		bool owned = false;
		owned = m_Mutex.WaitOne(TimeSpan.Zero,false);
		return owned ;
	}
	static void OnExit(object sender,EventArgs args)
	{
		m_Mutex.ReleaseMutex();
		m_Mutex.Close();
	}
}
public class MyForm : Form
{
   Label m_Label;

	public MyForm()
	{
		InitializeComponent();
	}
	private void InitializeComponent()
	{...}
	static void Main() 
	{
		SingletonApp.Run(new MyForm());
	}
}

