Saturday 28 June 2008

Array declaration in C# v VB.NET

One particular small thing that I prefer in C# over VB.NET is the way arrays are declared. In C# you declare the size of the array with the total number of elements, instead of the upper bound.

i.e. To declare an array of 10 integers in C#:

   1:  int[] myArray = new int[10];


To declare an array of 10 integers in VB:

   1:  Private myArray(9) As Integer


Other obvious differences are the use of square brackets for C# instead of the parentheses used with VB. Also, th array brackets are part of the type description, instead of the variable name.

In my opinion, the C# declaration seems more correct to me, and it has meant I am using less of the 'Array.Length - 1' syntax when using loops etc.


This is a good article in C# Corner that explains the use of arrays.

Thursday 26 June 2008

Gradient border around a form

Sometimes it is nice to have a bit of extra eye candy to look at, and a good place to have some of this is on a splash screen. One effect that is very simple to achieve is a custom border around the form with a bit of colour and maybe a gradient fill, which is what this post is about.

First of all, set a few of the form properties as follows:

FormBorderstyle - None.
ControlBox - False.
MaximizeBox - False.
MinimizeBox - False.

The FormBorderStyle property is set to false because the intention is to draw a custom border of our own.
The code required to actually draw the gradient border goes in the form's Paint event. This event is fired at any time the form needs to be redrawn, or in other words - Painted.

   1:  private void SplashForm_Paint(object sender, PaintEventArgs e)
   2:  {
   3:      // Get the form bounding rectangle
   4:      Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
   5:   
   6:      // Create the brush used to paint the border
   7:      LinearGradientBrush lgb = new LinearGradientBrush(
   8:                                        rect,
   9:                                        Color.DarkBlue,
  10:                                        Color.Blue,
  11:                                        LinearGradientMode.ForwardDiagonal);
  12:    
  13:      // Draw the border with a width of 10
  14:      e.Graphics.DrawRectangle(new Pen(lgb, 10), rect);
  15:   
  16:      // Dispose of the brush
  17:      lgb.Dispose();
  18:  }


This produces the subtle gradient around the splash screen to my Datalog application:



I hope it can be seen that is easy to change the colours, change the gradient and the size of the border that is drawn. Pretty straightforward and only four lines of code.

Sunday 15 June 2008

Watchdog timer

I had a need for a simple watchdog timer, to tick only when the time had elapsed, and also to be able to continuously restart it, to stop the timer from ticking.

This was an excuse to use some inheritance, as I took a standard System.Timers.Timer and subclassed it to create my own WatchdogTimer.

The code for this is below:

   1:  using System;
   2:  using System.Timers;
   3:   
   4:  namespace MyNamespace
   5:  {
   6:      public class WatchdogTimer : Timer
   7:      {
   8:          private double _timeout;
   9:   
  10:          public WatchdogTimer()
  11:            : base()
  12:          {
  13:          }
  14:   
  15:          public WatchdogTimer(double interval)
  16:            : base(interval)
  17:          {
  18:              this._timeout = interval;
  19:          }
  20:   
  21:          // Reset and restart the timer.
  22:          public void Restart()
  23:          {
  24:              // Resetting the interval property
  25:              // forces the timer to restart.
  26:              this.Interval = this._timeout;
  27:          }
  28:      }
  29:  }


It works once the timer has been started by conventional means (i.e. timer.Start();), then it is simply a matter of calling restart every time you need to. In my case it was because I am performing some serial or TCP communications functions, and needed a timeout should they fail.

Each time I sent a comms response, I expected to receive a response within an allotted period of time. If the response was received, then I called Restart() on the WatchdogTimer. If the response is not received, then the timer will timeout and 'Tick', allowing any code necessary to handle failed comms to run.

Saturday 14 June 2008

InvokeRequired

One thing that initially confused me when beginning to learn C# with Visual C# 2008 Express, was the complaints made by the debugger when a cross-thread operation was carried out while trying to modify a GUI Control object.

Doing this is a big no-no as it screws up the message pump operation used by Windows to service all GUI objects running on the user interface thread.

The solution to this is to use the .InvokeRequired property of the Control you are trying to access, as in the following code snippet:

   1:  private void SetText(String txt)
   2:  {
   3:      if (this.InvokeRequired)
   4:      {
   5:          BeginInvoke(new MethodInvoker(delegate() { this.SetText(txt); }));
   6:      }
   7:      else
   8:      {
   9:          // Update the text
  10:          this.Text = txt;
  11:      }
  12:  }


In this example, I want to change the title text of the form. To do this, the method SetText is called, and the InvokeRequired property is checked. If the calling thread is the same as the UI thread, InvokeRequired will be false, and the text can be modified with no problem.

However, if the calling thread is NOT the same as the UI, then InvokeRequired will be true, and as such the method is called again via the delegate call. This will ensure the SetText method is called from the UI thread and the text can be adjusted without any complaints form the debugger.

Visual C# 2008 Express

Having tried a bit of VB.NET, I have decided to have a go at learning some C#. To that end, I am using Visual C# 2008 Express from Microsoft. Not least because it is free!

The experience I gained with visual Basic has helped a lot with the initial learning curve of C#, as a lot of the statements are very similar. Some only require the addition of a semi-colon to convert it for example.

The C# language itself is very clean, compared to relative verbosity of Visual Basic, and I am picking it up well (at a beginner level at least.)

Biggest hurdle so far has been understanding Delegates and creating events. the methodology for this is far different than Visual Basic, in part because VB hides away most of the machinery for this, and so are not exposed to it as readily. C# however, requires you to do this stuff explicitly, which is hard at first.



As for the Express application, I am extremely impressed. It has all the functionality I could wish for as a single user at the beginner level. There is only one caveat to that, and that is the lack of a Setup and Install project template. Only ClickOnce technology is implemented, and to be honest, I find that inappropriate for my needs. I will investigate creating an installer for any apps using third party tools, such as Inno for example. I'm sure that will the subject of a future blog entry when the time comes.