NTDLS.WinFormsHelpers
1.5.0
See the version list below for details.
dotnet add package NTDLS.WinFormsHelpers --version 1.5.0
NuGet\Install-Package NTDLS.WinFormsHelpers -Version 1.5.0
<PackageReference Include="NTDLS.WinFormsHelpers" Version="1.5.0" />
<PackageVersion Include="NTDLS.WinFormsHelpers" Version="1.5.0" />
<PackageReference Include="NTDLS.WinFormsHelpers" />
paket add NTDLS.WinFormsHelpers --version 1.5.0
#r "nuget: NTDLS.WinFormsHelpers, 1.5.0"
#:package NTDLS.WinFormsHelpers@1.5.0
#addin nuget:?package=NTDLS.WinFormsHelpers&version=1.5.0
#tool nuget:?package=NTDLS.WinFormsHelpers&version=1.5.0
NTDLS.WinFormsHelpers
NTDLS.WinFormsHelpers is a small NuGet package of helper utilities for Windows Forms applications. It provides thread-safe extension methods for Control, Form and ListView that remove the boilerplate around cross-thread Invoke calls, validated value accessors for TextBox controls, tooltip helpers, a spinning ActivityIndicator user control, and a ready-made ProgressForm for running work on a background thread while reporting progress to the user.
📦 Be sure to check out the NuGet package: https://www.nuget.org/packages/NTDLS.WinFormsHelpers
When to use this package
Use NTDLS.WinFormsHelpers when you are writing a WinForms app and keep running into one or more of these problems:
- Cross-thread exceptions. Updating a label, list view, or dialog from a worker thread throws
InvalidOperationException. TheInvoke*extension methods handleInvokeRequiredfor you, so the same call works whether it runs on the UI thread or not. - Tedious input validation. You want a typed value out of a
TextBoxwith range or length checks, and a clear error message when the user enters something invalid. - Long-running operations. You need to run work off the UI thread while showing a progress form — including optional cancellation — without hand-rolling threads,
Invokes, and synchronization. - Polish. You want tooltips applied in bulk (with automatic text wrapping) or a lightweight spinning activity indicator.
If your app is pure console/server code, WPF, or Blazor, this package will not help you — it is strictly WinForms.
Usage examples
Thread-safe control updates
using NTDLS.WinFormsHelpers; // required for the extension methods
// Safe to call from any thread — no InvokeRequired check needed.
labelStatus.InvokeSetText("Working...");
buttonSave.InvokeDisable(); // disable while work is in flight
buttonSave.InvokeEnable(); // re-enable when done
// Close a dialog from a worker thread.
this.InvokeClose(DialogResult.OK);
// Show a message box from any thread; returns the button the user pressed.
DialogResult result = this.InvokeMessageBox("Done!", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
ListView updates from another thread
using NTDLS.WinFormsHelpers;
// All of these are safe to call from a background thread.
listView.InvokeClearRows(); // clear all items
listView.Items.Add(new ListViewItem("Item")); // then populate...
listView.InvokeDeleteItem(listView.Items[0]); // remove one item
listView.InvokeDeleteSelectedItems(); // remove everything selected
listView.InvokeClearSelection(); // deselect all
Sorting a ListView by column
using NetTunnel.UI.Helpers; // note: the comparer lives in this namespace
var comparer = new ListViewItemComparer { SortColumn = 1, SortOrder = SortOrder.Ascending };
listView.ListViewItemSorter = comparer;
listView.Sort(); // rows now sorted by column 1, ascending
Reading and validating TextBox values
using NTDLS.WinFormsHelpers;
// Parse and range-check an integer ([min]/[max] are substituted into the message).
int port = txtPort.GetAndValidateNumeric(1, 65535, "Port must be between [min] and [max].");
// Require non-empty text; throws with your message if the box is blank.
string name = txtName.GetAndValidateText("A name is required.");
// Convert the text to any type supported by the underlying converter.
decimal price = txtPrice.ValueAs<decimal>();
All validators throw an Exception carrying your message when the value is missing or out of range.
Tooltips
using NTDLS.WinFormsHelpers;
// Create a tooltip owned by the form — it disposes itself when the form closes.
ToolTip tips = this.CreateToolTipControl();
// Apply the same (soft-wrapped) text to several controls at once.
tips.AddControls(new Control[] { btnOpen, btnSave, btnCancel },
"Performs the action after validating all inputs.", wrapLength: 40);
ProgressForm for background work
using NTDLS.WinFormsHelpers;
// Runs the worker on a background thread, shows the progress form,
// and closes it automatically when the worker finishes.
var progress = new ProgressForm("Exporting", "Please wait", "Building the report...");
progress.Execute(sender =>
{
for (int i = 0; i < 100; i++)
{
DoWork(i);
sender.SetProgressValue(i + 1); // thread-safe progress update
if (sender.IsCancelPending) break; // honor the Cancel button
}
});
progress.Dispose();
There are async variants too (ExecuteAsync) and overloads that return a result:
// Fire-and-forget async work.
await progress.ExecuteAsync(async sender =>
{
await Task.Delay(2000);
});
// Async work that returns a value.
string result = await progress.ExecuteAsync<string>(async sender =>
{
return await GenerateReportAsync(sender);
});
You can also drive the form manually via ShowDialog(...), SetHeaderText, SetBodyText, IncrementProgressValue, SetCanCancel, and the OnCancel event.
ActivityIndicator control
using NTDLS.WinFormsHelpers.Controls;
var spinner = new ActivityIndicator
{
AutoIncrement = true, // rotate automatically
AutoIncrementFrequency = 80 // milliseconds per step
};
spinner.ActiveSegmentColor = Color.SteelBlue;
form.Controls.Add(spinner);
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0-windows7.0 is compatible. net10.0-windows was computed. net10.0-windows7.0 is compatible. |
-
net10.0-windows7.0
- NTDLS.Helpers (>= 1.4.0)
-
net9.0-windows7.0
- NTDLS.Helpers (>= 1.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.6.3 | 56 | 10/19/2026 |
| 1.6.1 | 55 | 10/19/2026 |
| 1.5.1 | 62 | 10/18/2026 |
| 1.5.0 | 61 | 10/17/2026 |
| 1.4.0 | 62 | 10/17/2026 |
| 1.3.14 | 143 | 9/5/2026 |
| 1.3.13 | 417 | 11/13/2025 |
| 1.3.12 | 188 | 8/23/2025 |
| 1.3.11 | 370 | 5/15/2025 |
| 1.3.10 | 250 | 5/9/2025 |
| 1.3.9 | 203 | 5/2/2025 |
| 1.3.8 | 243 | 3/2/2025 |
| 1.3.7 | 215 | 1/25/2025 |
| 1.3.6 | 202 | 1/23/2025 |
| 1.3.5 | 219 | 1/23/2025 |
| 1.3.4 | 306 | 12/31/2024 |
| 1.3.3 | 268 | 12/3/2024 |
| 1.3.2 | 231 | 11/1/2024 |
| 1.3.1 | 240 | 11/1/2024 |
| 1.3.0 | 233 | 10/22/2024 |
Dependency updates.