Category Archives: C#

Notes on C# / .NET

Enable double buffering without sub classing (Forms)

To enable double buffering on a control without subclassing it, use the method below. Double buffering is disabled in terminal server sessions since it will lower performance instead of increasing it.

public static void setDoubleBuffering(Control control, bool state)
{
   if (!System.Windows.Forms.SystemInformation.TerminalServerSession)
   {
      typeof(Control).InvokeMember("DoubleBuffered",
      System.Reflection.BindingFlags.NonPublic |
      System.Reflection.BindingFlags.Instance  |
      System.Reflection.BindingFlags.SetProperty,
      null,
      control, new object[] { state });
   }
}
Lastest update in September 2017, inital post in September 2017

Implement clone for a derived class.

In a derived class of a clonable class (implementing ICloneable) it is strongly advised
to implement the clone override. Obviously, this is only needed if new members have been
added.

for example:

class A : B
{
   int value1;
   public override object Clone()
   {
      A instance = (A)base.Clone();
      instance.value1 = value1;
      return (instance);
   }
}

The method Clone is being called from the context of A and creates an A object. Coming from a
C++ background this looks weird since you would expect a class of type B to be created. After
the initial Clone the extra member value1 has to be initialized as shown in the example.

Lastest update in September 2017, inital post in September 2017

Exact text start for DrawString with multiple font sizes.

Using DrawString texts have a horizontal spacing depending on their font size. In case of a list using multiple font sizes this looks strange. To start exactly at the same space use the following as a StringFormat argument for DrawString

StringFormat sFormat = new StringFormat(StringFormat.GenericTypographic);
Lastest update in April 2012, inital post in April 2012

Optionally execute a post-build executable

To execute a post-build command Visual C++ offers settings for both debug and release mode. Visual C# does not. To execute a post-build command based on debug or release mode use the following construct:

if $(ConfigurationName) == Release d:\test.exe $(TargetPath)
Lastest update in September 2017, inital post in April 2012

Showing time in DataGridView column

To show time in a DataGridView column set the column type to DataGridViewTextBoxColumn.
Set the columns DefaultCellStyle Format to ‘t’. You can do this in the designer or use the following code:

myGridView.Columns[0].DefaultCellStyle.Format = “t”; //0 is the required column, change if needed.

Now you can assign a DateTime to the cell value and time will show in the users preferred format (‘t’).

Lastest update in April 2012, inital post in April 2012

Check whether a form is valid.

When using modeless forms the user can close  the form manually. Use the created property to check whether this is the case.

Example:

class Form1 : Form
{
   Form2 modelessForm = null;

   //On mouse click show Form2
   void onMouseClick(MouseButtons button, int x, int y)
   {
      if (modelessForm == null || !modelessForm.Created)
      {
         modelessForm = new Form2()
      }

      modelessForm.Show();
   }
}
Lastest update in March 2012, inital post in March 2012

Parsing values out of strings using culture independend settings

When parsing a value out of a string the current separator is used. In English this is a dot. In other languages a comma is being used.
When parsing a string the current culture setting is being used!

To ensure the dot is being used as separator use the method below:

double value = Convert.ToDouble(text, CultureInfo.InvariantCulture);
Lastest update in March 2012, inital post in March 2012

Executing a SQL stored procedure and read the result

Self explanatory snippet

SqlConnection db = new SqlConnection(Properties.Settings.Default.ConnectionString);

try
{
   db.Open();

   SqlCommand cmd = new SqlCommand("storedProcedureName", db);
   cmd.CommandType = CommandType.StoredProcedure;
   cmd.Parameters.Add(new SqlParameter("@parm1", SqlDbType.Int, 4));
   cmd.Parameters.Add(new SqlParameter("@parm2", SqlDbType.Text));
   cmd.Parameters["@parm1"].Value = 1234;
   cmd.Parameters["@parm2"].Value = "ABC";

   SqlDataReader dataReader = cmd.ExecuteReader();

   DataTable storedTable = new DataTable();
   storedTable.Load(dataReader);
                
   foreach (DataRow row in storedTable.Rows)
   {
      //Here row contains the retrieved data.
      int test = Convert.ToInt32(row[0]);
   }
   storedTable.Dispose();
   dataReader.Dispose();
   cmd.Dispose();
          
   db.Close(); 
   db.Dispose(); 
   db = null;
}
catch (Exception e)
{
   System.Windows.Forms.MessageBox.Show(e.Message, "DB error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);      
}

Lastest update in February 2012, inital post in February 2012