CSharp Tips

This is a small collection of code samples, i wrote for my personal use. Later i decided to make it public, like my other pages for Delphi and PHP code. The functions are all free and tested and most of them are written by myself.

If you found something useful, i'm happy to hear about it. Also suggestions to the functions are very welcome, don't hesitate to send me an email to .

Overview


String functions

Using text resources of Windows

Did you already write a small useful function for your library, but then it became difficult to share it, because you needed to deliver translated text resources? Maybe you can borrow the textes from the Windows environment, at least some of the most common textes. To find out which text resources are available, just open the windows library in VisualStudio and switch to the String-Table node.

using System;
using System.Runtime.InteropServices;
using System.Text;

/// <summary>
/// Searches for a text resource in a Windows library. Sometimes, using the
/// existing Windows resources, you can make your code language independent
/// and you don't have to care about translation problems.
/// </summary>
internal class Sto_WindowsString
{
  /// <summary>
  /// Searches for a text resource in a Windows library.
  /// </summary>
  /// <example>
  ///   btnCancel.Text = Sto_WindowsString.Load("user32.dll", 801, "Cancel");
  ///   btnYes.Text = Sto_WindowsString.Load("user32.dll", 805, "Yes");
  /// </example>
  /// <param name="libraryName">Name of the windows library like "user32.dll"
  /// or "shell32.dll"</param>
  /// <param name="ident">Id of the string resource.</param>
  /// <param name="defaultText">Return this text, if the resource string could
  /// not be found.</param>
  /// <returns>Requested string if the resource was found,
  /// otherwise the <paramref name="defaultText"/></returns>
  public static string Load(string libraryName, uint ident, string defaultText)
  {
    IntPtr libraryHandle = GetModuleHandle(libraryName);
    if (libraryHandle != IntPtr.Zero)
    {
      StringBuilder sb = new StringBuilder(1024);
      int size = LoadString(libraryHandle, ident, sb, 1024);
      if (size > 0)
        return sb.ToString();
    }
    return defaultText;
  }

  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  private static extern IntPtr GetModuleHandle(string lpModuleName);

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
}

Algorithms

Stable and parallel Mergesort

When you call the sort method of a list or of an array, you will finally use the Array.Sort() function, which implements a fast Quicksort. This can be very handy, but especially when you have to sort a list of objects with multiple attributes (like database records), there are some drawbacks. Because of these drawbacks, and because i couldn't find code for a parallel and stable sorting, i implemented a Mergesort, with following advantages over the built-in sort function:

  1. The Mergesort is stable, this means that equal elements will preserve their relative position and won't get mixed up. This allows the user to first sort by one attribute, and afterwards by another attribute.
  2. The implementation is done parallel, so it can take advantage of several available processor cores.
  3. The Mergesort needs much less comparisons. While copying objects is a cheap pointer operation, the comparison of two objects can be quite expensive.

View class: StoParallelMergeSort.cs
Download sourcecode: StoParallelMergeSort.zip


GUI

Loading TreeView on demand (lazy loading)

The TreeView component can be used as a virtual tree. It's not necessary to initialize the tree with all data, instead you can populate the child nodes, when the user expands a node. Unfortunately, the TreeView does not display the plus icon on a node without child nodes, and therefore the user cannot expand the TreeNode. This is a way to display the plus icon, without adding a dummy child node (as one can often see).

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

/// <summary>
/// Helps using a TreeView as virtual tree, that can populate its nodes on demand.
/// </summary>
internal class StoLazyTreeView
{
  /// <summary>
  /// Makes the plus icon of a tree node visible or hides it, independend of
  /// whether the node has child nodes. This allows to populate a tree on demand.
  /// </summary>
  /// <param name="node">Set the plus icon for this node.</param>
  /// <param name="visible">Determines wheter to show or to hide the plus.</param>
  public static void SetPlusIcon(TreeNode node, bool visible)
  {
    // prevent hiding the icon, when already child nodes exist
    if ((node.Nodes.Count > 0) && (visible == false)) return;

    TV_ITEM lParam = new TV_ITEM()
      {
        mask = TVIF_CHILDREN,
        hItem = node.Handle,
        cChildren = Convert.ToInt32(visible)
      };
    HandleRef treeHandleRef = new HandleRef(node.TreeView, node.TreeView.Handle);
    SendMessage(treeHandleRef, TVM_SETITEM, 0, ref lParam);
  }

  [DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern IntPtr SendMessage(
    HandleRef hWnd, int msg, int wParam, ref TV_ITEM lParam);

  private const int TVIF_CHILDREN = 0x40;
  private const int TVM_SETITEM = 0x110d;

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  private struct TV_ITEM
  {
    public int mask;
    public IntPtr hItem;
    public int state;
    public int stateMask;
    public IntPtr pszText;
    public int cchTextMax;
    public int iImage;
    public int iSelectedImage;
    public int cChildren;
    public IntPtr lParam;
  }
}

www.martinstoeckli.ch