static void

WinForms.Net

Scrappy notes because I'm primarily a web developer

Events

Note the order: Enter - GotFocus - TextChanged - Leave - Validating - Validated - LostFocus
TextBox can be ReadOnly (gets focus), !Enabled (no focus).
Validation levels:

GDI+

Is also used with the PrintPage event of the PrintDocument component
Graphics object is available from a form1.CreateGraphics factory method (anything Control-derived), from PaintEventArgs(or PrintPageEventArgs).Graphics, or the static Graphics.FromImage(img)
Draw* for lines (with a Pen), Fill* for filled shapes (with a Brush).
Pen myPen = new Pen(myBrush)
Coordinates: Point, Size, Rectangle (a Size with a Point as origin).

g.DrawString(str, new Font("Arial", 36, FontStyle.Regular), myPen, 0, 0);
Dispose all Pens/Brushes/Graphics objects (enclose them in using)
GraphicsPaths- is for complex shapes- use AddString etc, StartFigure/CloseFigure

Authoring Controls

Add toolbox icons- [ToolboxBitmap(typeof(Button))]. Or pass the path, or simply put add YourClassName.bmp as an embedded resource (bmp filename== classname) and it does it magically.
You can also use LicenseManager.Validate.

Help

Settings

WinForms 2.0 designer - properties - Application Settings/ PropertyBindings creates the Settings class and binds for you. (msdn)
For C# (not VB) you need:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    Properties.Settings.Default.Save();
}

Tooltips on TreeView treenodes

Option 1: treeview1.ShowNodeToolTips = true and set the treeNode's ToolTipText
Option 2: Add a Windows.Forms.ToolTip, and handle the treeview's MouseMove event. You can use the treeNode's ToolTipText directly, or cast the Tag. You need to remember the last node or tooltip to avoid unpleasant repeat flashing as the cursor moves.

private string lastNode; //remember tooltips to avoid flashing
private void DatabaseScripterTreeView_MouseMove(object sender, MouseEventArgs e)
{
    // Get the node at the current mouse pointer location.
    TreeNode theNode = GetNodeAt(e.X, e.Y);
 
    // if mouse not over a node, or it has no tag, no tooltip
    if (theNode == null || string.IsNullOrEmpty(theNode.ToolTipText))
    {
        toolTip1.Active = false;
        lastNode = null;
        return;
    }
 
    //check still on same node - otherwise fires repeatedly
    if (theNode.ToolTipText == lastNode) return;
    lastNode = theNode.ToolTipText;
 
    //show the tooltip
    var tag = theNode.ToolTipText;
 
    if (!toolTip1.Active) toolTip1.Active = true;
    toolTip1.SetToolTip(this, tag);
}

CrossThread Pattern

For the dreaded cross-thread exception. You can either define a delegate or use an Action/ Func (or new MethodInvoker- anonymous delegates don't work).

void Model_Changed(object sender, EventArgs e)
{
    //model changed by background worker or UI
    UpdateUI();
}
 
/// <summary>
/// Updates the UI in a threadsafe way
/// </summary>
private void UpdateUI()
{
    if (InvokeRequired)
    {
        //call myself on the windows thread
        Invoke(new Action(UpdateUI));
    }
    else
    {
        txtName.Text = "Hello";
    }
}