Posts Tagged ‘WinForms’

HowTo: use a Timer component for delayed execution in WinForms

This is my contribution to:

Sometimes a Timer component is useful and easy to setup in WinForms, just set its interval and then enable it, then make sure the first thing you do in its Tick event handler is to disable itself.

I think Timer runs the code in its own thread, so you may still need to do a BeginInvoke (called upon the WinForm object [this]) to run your Action.


private WebBrowserDocumentCompletedEventHandler handler;
//need to make it a class field for the handler below
//(anonymous delegates seem to capture state at point of
// definition, so they can't capture their own reference)
private string imageFilename; private bool exit; public void CaptureScreenshot(
Uri address = null,
string imageFilename = null,
int msecDelay = 0,
bool exit = false) { handler = (s, e) => { webBrowser.DocumentCompleted -= handler; //must do first this.imageFilename = imageFilename; this.exit = exit; timerScreenshot.Interval = (msecDelay>0)? msecDelay : 1; timerScreenshot.Enabled = true; }; webBrowser.DocumentCompleted += handler; Go(address); //if address == null, will use URL from UI } private void timerScreenshot_Tick(object sender, EventArgs e) { timerScreenshot.Enabled = false; //must do first BeginInvoke((Action)(() => //Invoke at UI thread { //run in UI thread BringToFront(); Bitmap bitmap = webBrowser.GetScreenshot(); if (imageFilename == null) imageFilename = bitmap.ShowSaveFileDialog(); if (imageFilename != null) { Directory.CreateDirectory(
//create any parent directories needed bitmap.Save(imageFilename); } bitmap.Dispose(); //release bitmap resources if (exit) Close(); //this should close the app, this is main form }), null); }

You can see the above in action at ClipFlair‘s WebCapture tool (, source code at:, see Tools/WebCapture folder) that grabs screenshots from websites.

BTW, if you want to call the executable from command-line make sure you go to Properties of the project and at Security tab turn-off ClickOnce security (else it can’t access command-line).

HowTo: Display version information on WinForm title

This is my contribution to

I’m using the following at the WinForm of the WebCapture tool I’m making for ClipFlair:

public MainForm()
  Version version = Assembly.GetExecutingAssembly().GetName().Version;
  Text = Text + " " + version.Major + "." + version.Minor + 
" (build " + version.Build + ")"; //change form title }

Not showing revision number to the user, build number is enough technical info

Make sure your AssemblyInfo.cs ends in the following (remove the version it has there by default) for VisualStudio to autoincrement build and revision number. You have to update major and minor versions yourself at every release (update major version for new features, minor version when you do just fixes):

// Version information for an assembly consists of the following four values:
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
// You can specify all the values or you can default the Build
// and Revision Number by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.*")]

Update: Since now WebCapture is ClickOnce-deployed from the web (also has nice autoupdate support thanks to ClickOnce) and I want to avoid user confusion by showing the published version of the app (as the ClickOnce installation page does) on the WinForm titlebar, I now use the following code instead, based on a relevant post I found on the web:

public MainForm()





private void ShowVersion()


  Version version = (ApplicationDeployment.IsNetworkDeployed)?

    ApplicationDeployment.CurrentDeployment.CurrentVersion :


    //if network deployed show published version (as the web install page)

  Text = Text + " " + version.Major + "." + version.Minor + "."

                     + version.Build + "." + version.Revision;

                       //change form title


BTW, speaking of ClickOnce, I noticed that if at the autoupdate dialog shown when you launch the app from its desktop shortcut (and there’s a new version available) you press “Skip”, it won’t offer you this update anymore when you launch an app (I hope that when an even newer update is there it will prompt you), but you can override that behaviour by going to the installation page for your ClickOnce app (where you installed it from in the first place) and press the “Install” button there.

HowTo: Save screenshot of a control hosted on a WinForm

I’m trying to automate grabbing of activity screenshots from ClipFlair Activity Gallery, but most command-line screen capturing tools, like SiteShoter and IECapt fail to get an image from Silverlight content (they get just a background color).

Some other opensource tool that I could tweek was ThumbPage, but  that didn’t support command-line and needed to disable Silverlight hardware acceleration in the webpage source (that is not define enableGPUAcceleration Silverlight param or set it to false) to grab the Silverlight content too in the image. This is probably because that tool was written in VB6 and must be using plain GDI instead of GDI+ or other newer graphics API, but I’m not sure if that’s the issue with the h/w acceleration.

So, I started making my own WinForms-based tool in Visual Studio. The following sample code is based on ArsenMkrt’s reply at StackOverflow, but this one allows you to capture a control in your form (my tool has a WebBrowser control in it and want to capture just its display). Note the use of PointToScreen method:

//Project: WebCapture
//Filename: ScreenshotUtils.cs
//Author: George Birbilis (
//Version: 20130820

using System.Drawing;
using System.Windows.Forms;

namespace WebCapture
  public static class ScreenshotUtils

    public static Rectangle Offseted(this Rectangle r, Point p)
      return r;

    public static Bitmap GetScreenshot(this Control c)
      return GetScreenshot(new Rectangle(c.PointToScreen(Point.Empty), c.Size));

    public static Bitmap GetScreenshot(Rectangle bounds)
      Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
      using (Graphics g = Graphics.FromImage(bitmap))
        g.CopyFromScreen(new Point(bounds.Left, bounds.Top), 
                         Point.Empty, bounds.Size);
      return bitmap;

    public const string DEFAULT_IMAGESAVEFILEDIALOG_TITLE = "Save image";
"PNG Image (*.png)|*.png|JPEG Image (*.jpg)|*.jpg|Bitmap Image (*.bmp)|
*.bmp|GIF Image (*.gif)|*.gif";

//*** NOTE: the string above is a single line, split it for posting here ***//

    public static SaveFileDialog GetImageSaveFileDialog(
      SaveFileDialog dialog = new SaveFileDialog();

      dialog.Title = title;
      dialog.Filter = filter;

      return dialog;

    public static void ShowSaveFileDialog(this Image image, 
                                          IWin32Window owner = null)
      using (SaveFileDialog dlg = GetImageSaveFileDialog())
        if (dlg.ShowDialog(owner) == DialogResult.OK)


Note the “using” clause above, it makes sure that the local variable g of type Graphics is Disposed immediately after the respective clause exits, instead of leaving any allocated resources for the garbage collector to handle. Plus the compiler makes sure the “g” variable isn’t use at the following code in that method by mistake (which could occur if you disposed it there by hand instead).

Having the Bitmap object you can just call Save on it:

private void btnCapture_Click(object sender, EventArgs e)
  webBrowser.GetScreenshot().Save("C://test.jpg", ImageFormat.Jpeg);

The above assumes the Garbage Collector (aka GC) will grab the bitmap, but maybe it’s better to assign the result of someControl.getScreenshot() to a Bitmap variable, then dispose that variable manually when finished, especially if you’re doing this grabbing often (say you have a list of webpages you want to load and save screenshots of them):

private void btnCapture_Click(object sender, EventArgs e)
  Bitmap bitmap = webBrowser.GetScreenshot();
  bitmap.Dispose(); //release bitmap resources



Now WebCapture tool is ClickOnce-deployed from the web (also has nice autoupdate support thanks to ClickOnce) and you can find its source code at

Speaking of ClickOnce, I noticed that if at the autoupdate dialog shown when you launch the app from its desktop shortcut (and there’s a new version available) you press “Skip”, it won’t offer you this update anymore when you launch an app (I hope that when an even newer update is there it will prompt you), but you can override that behaviour by going to the installation page for your ClickOnce app (where you installed it from in the first place) and press the “Install” button there.

Save file dialog with Encoding dropdown

found a nice Save file dialog for .NET that adds an Encoding dropdown
see discussion at the end of that article for my version of that C# code, with some fixes and enhancements (I recently reworked all that into an even better dialog, which accepts/returns a System.Text.Encoding type and shows the list of all encodings provided by the .NET rutime [this includes, apart from the various Unicode flavours, all installed codepages at the OS as it seems]. If interested on it contact me privately to send you a trial)
only glitch is that on XP at the last shortcut folder button on the left handside of the dialog, the bottom part doesn’t show exactly right (maybe not noticeable by most people) when hovering. Haven’t tried it on Vista, hope it works ok there too
Categories: Uncategorized Tags:

Time/Date slider (trackbar) component for .NET WinForms

for using only with time, use custom format of the style "hh:mm:ss.ff" (remember to set it to use the custom format instead of the predefined ones)

the only thing that doesn’t seem to work OK is the "ShowSegment" property – it doesn’t draw the red underline bar for the current time selection at the correct position

Categories: Uncategorized Tags:

Flexible table components for .NET WinForms


quite mature

a bit underdeveloped, but interesting in that it tries to mimic JTable of Java/Swing. One could try J# Supplemental UI library instead, but J# Swing (sup ui lib) controls don’t interoperate with WinForms unfortunately (don’t know if anyone made a host control using reflection)

Categories: Uncategorized Tags:

Delphi-like ActionList component for .NET WinForms

note that to add event handler for an action you have to first select
if from the component selector dropdownbox that is at the top of the
properties window of (can’t select it at the actions collection

I suggest rebuilding the sourcecode with .NET 2 ( 2005), although the DLL seems to work ok even without doing that

Categories: Uncategorized Tags:

Most Recently Used (MRU) component for .NET 2.0 WinForms

This very nice component was made for .NET 1.1 WinForms MenuBar control. If you scroll down that page to the discussions you’ll see a posting of mine with the code I converted to make it work with .NET 2.0 WinForms MenuStrip control

other .net 2.0 mru library is (for .NET2’s MenuStrip)

but it’s not a component and one has to write code to use it

Categories: Uncategorized Tags:
%d bloggers like this: