What mechanisms does .Net provide to convert one type to another

Type conversion is usually possible in one of the following ways: 1) Using explicit methods in source type like: public class SizeF { … public Size ToSize(); } There is usually a corresponding explicit or implicit operator that does the same conversion. The operators are however not available in VB.Net. 2) Using FromXXX static methods exposed in the destination type: class Image { … public static Image FromStream(Stream); } 3) Using implicit or explicit operators defined in the source or destination type. This will allow you to perform implicit or explicit casts from the source type to the destination type. SizeF sizeF = size; // Possible because type Size has an implicit type conversion operator that converts a Size to SizeF PointF pointF = (PointF)sizeF; // Possible because type SizeF has an explicit type conversion operator that converts a SizeF to PointF. There is usually a corresponding ToXXX method that does the same conversion. You can use either this or the ToXXX methods in C#. 4) Using TypeConverters. Some types come with TypeConverters that allow you to convert to or convert from another type. This conversion is usually not documented and can be discovered only by writing some test code. For example, the System.Drawing.Icon type’s TypeConverter converts the Icon into a byte[]. You can use this functionality in your code as follows: TypeConverter tc = TypeDescriptor.GetConverter(typeof(System.Drawing.Icon)); byte[] blob = tc.ConvertTo(myIcon, typeof(byte[])); It’s usually time consuming to figure out whether a TypeConverter’s ConvertTo or ConvertFrom method can perform the necessary conversion. The attached TypeConverterLookup tool lets you figure that out easily on any type declared in any assembly available in the GAC or available in the same directory as the tool’s exe. If you have types in custom assemblies, then just copy over that assembly to the same directory as the tool, you can then specify the type in the tool.

How do I color a individual cell depending upon its value or some external method

We give three different methods for doing this. The first one overrides Paint in a derived columnstyle and sets the backcolor there. The second uses a delegate to set the color in the Paint override. The third method adds an event to the derived column style to allow you to set the color in an event handler. Method 1 You can do this by deriving from DataGridTextBoxColumn and overriding the Paint method to conditionally set the backColor and foreColor. The sample code below colors any cell that starts with a letter higher than ’F’. You can download a project (C#, VB) using this class. [C#] public class DataGridColoredTextBoxColumn : DataGridTextBoxColumn { protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight) { // the idea is to conditionally set the foreBrush and/or backbrush // depending upon some criteria on the cell value // Here, we color anything that begins with a letter higher than ’F’ try{ object o = this.GetColumnValueAtRow(source, rowNum); if( o!= null) { char c = ((string)o)[0]; if( c > ’F’) { // could be as simple as // backBrush = new SolidBrush(Color.Pink); // or something fancier… backBrush = new LinearGradientBrush(bounds, Color.FromArgb(255, 200, 200), Color.FromArgb(128, 20, 20), LinearGradientMode.BackwardDiagonal); foreBrush = new SolidBrush(Color.White); } } } catch(Exception ex){ /* empty catch */ } finally{ // make sure the base class gets called to do the drawing with // the possibly changed brushes base.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight); } } } [VB.NET} Public Class DataGridColoredTextBoxColumn Inherits DataGridTextBoxColumn Public Sub New() 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) ’ the idea is to conditionally set the foreBrush and/or backbrush ’ depending upon some crireria on the cell value ’ Here, we color anything that begins with a letter higher than ’F’ Try Dim o As Object o = Me.GetColumnValueAtRow(source, rowNum) If (Not (o) Is Nothing) Then Dim c As Char c = CType(o, String).Substring(0, 1) If (c > ”F”) Then ’ could be as simple as ’ backBrush = new SolidBrush(Color.Pink); ’ or something fancier… backBrush = New LinearGradientBrush(bounds, Color.FromArgb(255, 200, 200), Color.FromArgb(128, 20, 20), LinearGradientMode.BackwardDiagonal) foreBrush = New SolidBrush(Color.White) End If End If Catch ex As Exception ’ empty catch Finally ’ make sure the base class gets called to do the drawing with ’ the possibly changed brushes MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight) End Try End Sub End Class Method 2 To use some method to provide the cell color, you can use a similar technique as discussed above. But instead of setting the color based on cell value, call a delegate method instead. This delegate can be passed in using the constructor for the custom column style. You can download a sample that shows how this can be done. Method 3 If you want a more flexible solution, you could expose an event as part of your derived columnstyle that fires in the Paint override. This would allow the handler of the event to set the color value depending upon the row and column parameters that are passed as part of the event args. You can download a sample (C#, VB) that implements this technique. The sample actually handles allowing a cell to be editable on a cell by cell basis through an event. This sample colors the back ground of the disabled cell gray. You could modify the eventargs to include a backcolor, and use this event to color cells based on row and column values removing the event call in the Edit override.

How can I create an instance of a Form class just from knowing its name in a string

You can use the System.Reflection.Assembly.CreateInstance method to create a form from its name. Below is a code snippet. The name in the textbox has to be the full name including its namespace. So if there is a class named Form2 in namespace MyCompanyName, then the textbox would contain MyCompanyName.Form2. This snippet also assumes that the class is defined in the current executing assembly. If not, you would have to create an instance of the assembly that contains the class instead of calling the static method GetExecutingAssembly. As noted on this board, using reflection in this manner might affect performance. You can download working samples (VB.NET, C#). [C#] try { Assembly tempAssembly = Assembly.GetExecutingAssembly(); // if class is located in another DLL or EXE, use something like // Assembly tempAssembly = Assembly.LoadFrom(”myDLL.DLL”); // or // Assembly tempAssembly = Assembly.LoadFrom(”myEXE.exe”); Form frm1 = (Form) tempAssembly.CreateInstance(textBox1.Text);// as Form; frm1.Show(); } catch(Exception ex) { MessageBox.Show(”Error creating: ”+ textBox1.Text); } [VB.NET] textBox1.Text = ”MyNameSpace.Form2” …… Try Dim tempAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly() ’ if class is located in another DLL or EXE, use something like ’ tempAssembly = Assembly.LoadFrom(”myDLL.DLL”) ’ or ’ tempAssembly = Assembly.LoadFrom(”myEXE.exe”) Dim frm1 As Form = CType(tempAssembly.CreateInstance(textBox1.Text), Form) ’ as Form; frm1.Show() Catch ex As Exception MessageBox.Show(”Error creating: ” + ex.ToString()) End Try

With a wide pen, how can I control how the endpoints of my line appear

The LineCap property of the Pen class controls how the ends of your line segments appear. You can set each end independently using the StartCap and EndCap properties of the Pen class. The following code segment produces the picture below. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { Pen redPen = new Pen(Color.LightSalmon, 20); int startX = 80; int startY = 30; int width = this.ClientSize.Width – 2 * startX; Font _font = new Font(“Arial Black”, 13); foreach(LineCap LC in new LineCap[] { LineCap.ArrowAnchor, LineCap.DiamondAnchor, LineCap.Flat, LineCap.Round, LineCap.RoundAnchor, LineCap.Square, LineCap.SquareAnchor, LineCap.Triangle}) { redPen.StartCap = LC; redPen.EndCap = LC; Point p1 = new Point(startX, startY); Point p2 = new Point(startX + width, startY); e.Graphics.DrawLine(redPen, p1, p2); e.Graphics.DrawString( LC.ToString(), _font, new SolidBrush(Color.Blue), startX + 40, startY – 13 ); startY += 50; } }

How do I add an unbound column to my bound datagrid

The idea is to create the ’bound’ table in your dataset, and then add an extra ’unbound’ column. The steps are to derive a custom columnstyle that overrides Paint where you calculate and draw the unbound value. You can also override Edit to prevent the user from selecting your unbound column. Then to get your datagrid to use this special column style, you create a tablestyle and add the column styles to it in the order you want the columns to appear in the datagrid. Here are code snippets that derive the column and use the derived column. You can download a working sample. // custom column style that is an unbound column public class DataGridUnboundColumn : DataGridTextBoxColumn { protected override void Edit(System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible) { //do not allow the unbound cell to become active if(this.MappingName == ”UnBound”) return; base.Edit(source, rowNum, bounds, readOnly, instantText, cellIsVisible); } protected override void Paint(System.Drawing.Graphics g, System.Drawing.Rectangle bounds, System.Windows.Forms.CurrencyManager source, int rowNum, System.Drawing.Brush backBrush, System.Drawing.Brush foreBrush, bool alignToRight) { //clear the cell g.FillRectangle(new SolidBrush(Color.White), bounds); //compute & draw the value //string s = string.Format(”{0} row”, rowNum); // col 0 + 2 chars from col 1 DataGrid parent = this.DataGridTableStyle.DataGrid; string s = parent[rowNum, 0].ToString() + ((parent[rowNum, 1].ToString())+ ” ”).Substring(0,2); Font font = new Font(”Arial”, 8.25f); g.DrawString(s, font, new SolidBrush(Color.Black), bounds.X, bounds.Y); font.Dispose(); } } //code that uses this unbound column private void Form1_Load(object sender, System.EventArgs e) { // Set the connection and sql strings // assumes your mdb file is in your root string connString = @”Provider=Microsoft.JET.OLEDB.4.0;data source=C:\northwind.mdb”; string sqlString = ”SELECT * FROM customers”; OleDbDataAdapter dataAdapter = null; DataSet _dataSet = null; try { // Connection object OleDbConnection connection = new OleDbConnection(connString); // Create data adapter object dataAdapter = new OleDbDataAdapter(sqlString, connection); // Create a dataset object and fill with data using data adapter’s Fill method _dataSet = new DataSet(); dataAdapter.Fill(_dataSet, ”customers”); connection.Close(); } catch(Exception ex) { MessageBox.Show(”Problem with DB access-\n\n connection: ” + connString + ”\r\n\r\n query: ” + sqlString + ”\r\n\r\n\r\n” + ex.ToString()); this.Close(); return; } // Create a table style that will hold the new column style // that we set and also tie it to our customer’s table from our DB DataGridTableStyle tableStyle = new DataGridTableStyle(); tableStyle.MappingName = ”customers”; // since the dataset has things like field name and number of columns, // we will use those to create new columnstyles for the columns in our DB table int numCols = _dataSet.Tables[”customers”].Columns.Count; //add an extra column at the end of our customers table _dataSet.Tables[”customers”].Columns.Add(”Unbound”); DataGridTextBoxColumn aColumnTextColumn ; for(int i = 0; i < numCols; ++i) { aColumnTextColumn = new DataGridTextBoxColumn(); aColumnTextColumn.HeaderText = _dataSet.Tables[”customers”].Columns[i].ColumnName; aColumnTextColumn.MappingName = _dataSet.Tables[”customers”].Columns[i].ColumnName; tableStyle.GridColumnStyles.Add(aColumnTextColumn); //display the extra column after column 1. if( i == 1) { DataGridUnboundColumn unboundColStyle = new DataGridUnboundColumn(); unboundColStyle.HeaderText = ”UnBound”; unboundColStyle.MappingName = ”UnBound”; tableStyle.GridColumnStyles.Add(unboundColStyle); } } // make the dataGrid use our new tablestyle and bind it to our table dataGrid1.TableStyles.Clear(); dataGrid1.TableStyles.Add(tableStyle); dataGrid1.DataSource = _dataSet.Tables[”customers”]; } }