Skip to content

Instantly share code, notes, and snippets.

@MatthewKing
Last active April 26, 2021 10:29
Show Gist options
  • Save MatthewKing/5506955 to your computer and use it in GitHub Desktop.
Save MatthewKing/5506955 to your computer and use it in GitHub Desktop.
Extension methods for classes in the System.Windows.Forms namespace.
// Copyright Matthew King 2012-2015.
// Distributed under the Boost Software License, Version 1.0.
// (See http://www.boost.org/LICENSE_1_0.txt)
using System;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
/// <summary>
/// Extension methods for classes in the System.Windows.Forms namespace.
/// </summary>
public static class WinFormExtensions
{
/// <summary>
/// Checks if this System.Windows.Forms.TreeNode is a descendant of the specified
/// System.Windows.Forms.TreeNode.
/// </summary>
/// <param name="node">
/// A System.Windows.Forms.TreeNode instance.
/// </param>
/// <param name="ancestor">
/// The System.Windows.Forms.TreeNode instance that is a potential ancestor of this
/// System.Windows.Forms.TreeNode instance.
/// </param>
/// <returns>
/// true if this System.Windows.Forms.TreeNode is a descendant of the specified
/// System.Windows.Forms.TreeNode; otherwise, false.
/// </returns>
public static bool IsDescendantOf(this TreeNode node, TreeNode ancestor)
{
if (node == null)
throw new ArgumentNullException("node", "node should not be null.");
if (ancestor == null)
throw new ArgumentNullException("ancestor", "ancestor should not be null.");
if (node.Parent == null)
return false;
if (node.Parent == ancestor)
return true;
return WinFormExtensions.IsDescendantOf(node.Parent, ancestor);
}
/// <summary>
/// Checks if this System.Windows.Forms.TreeNode is an ancestor of the specified
/// System.Windows.Forms.TreeNode.
/// </summary>
/// <param name="node">
/// A System.Windows.Forms.TreeNode instance.
/// </param>
/// <param name="descendant">
/// The System.Windows.Forms.TreeNode instance that is a potential descendant of this
/// System.Windows.Forms.TreeNode instance.
/// </param>
/// <returns>
/// true if this System.Windows.Forms.TreeNode is an ancestor of the specified
/// System.Windows.Forms.TreeNode; otherwise, false.
/// </returns>
public static bool IsAncestorOf(this TreeNode node, TreeNode descendant)
{
if (node == null)
throw new ArgumentNullException("node", "node should not be null.");
if (descendant == null)
throw new ArgumentNullException("descendant", "descendant should not be null.");
if (node.Nodes.Count == 0)
return false;
if (node.Nodes.Contains(descendant))
return true;
return node.Nodes
.OfType<TreeNode>()
.Any(n => WinFormExtensions.IsAncestorOf(n, descendant));
}
/// <summary>
/// Shows the form to the user.
/// </summary>
/// <param name="form">
/// The form to show.
/// </param>
/// <returns>
/// A task representing the asynchronous operation.
/// </returns>
public static Task<DialogResult> ShowAsync(this Form form)
{
if (form == null)
throw new ArgumentNullException("form", "form should not be null.");
return ShowAsync(form, null);
}
/// <summary>
/// Shows the form with the specified owner to the user.
/// </summary>
/// <param name="form">
/// The form to show.
/// </param>
/// <param name="owner">
/// Any object that implements System.Windows.Forms.IWin32Window and represents
/// the top-level window that will own the form.
/// </param>
/// <returns>
/// A task representing the asynchronous operation.
/// </returns>
public static Task<DialogResult> ShowAsync(this Form form, IWin32Window owner)
{
if (form == null)
throw new ArgumentNullException("form", "form should not be null.");
TaskCompletionSource<DialogResult> tcs = new TaskCompletionSource<DialogResult>();
FormClosingEventHandler handler = null;
handler = new FormClosingEventHandler((s, e) =>
{
form.FormClosing -= handler;
tcs.SetResult(form.DialogResult);
});
form.FormClosing += handler;
form.Show(owner);
return tcs.Task;
}
/// <summary>
/// Shows the System.Windows.Forms.ContextMenuStrip relative to the specified
/// System.Windows.Forms.Control location.
/// </summary>
/// <param name="menu">
/// The System.Windows.Forms.ContextMenuStrip to show.
/// </param>
/// <param name="control">
/// The System.Windows.Forms.Control that is the reference point for the
/// System.Windows.Forms.ContextMenuStrip position.
/// </param>
/// <param name="pos">
/// The horizontal and vertical location of the reference control's upper-left corner,
/// in pixels.
/// </param>
/// <returns>
/// A task representing the asynchronous operation.
/// </returns>
public static Task ShowAsync(this ContextMenuStrip menu, Control control, Point pos)
{
if (menu == null)
throw new ArgumentNullException("menu", "menu should not be null.");
if (control == null)
throw new ArgumentNullException("control", "control should not be null.");
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
ToolStripDropDownClosedEventHandler handler = null;
handler = new ToolStripDropDownClosedEventHandler((s, e) =>
{
menu.Closed -= handler;
tcs.SetResult(true);
});
menu.Closed += handler;
menu.Show(control, pos);
return tcs.Task;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment