TDStack.cs

Custom Dynamic Concurrent Stack Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class TDStack<T> : IEnumerable<T>
{
    private          T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public TDStack(int sizeHint)
    {
        if (sizeHint < 4)
            throw new Exception("Size must be greater than or equal to 4.");
        _array = new T[sizeHint];
        _maf   = new MonitorActionFunc();
        Count  = 0;
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, _array.Length);
            Count = 0;
        });
    }
    public T Pop()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            Interlocked.Decrement(ref Count);
            var TVal = _array[Count];
            _array[Count] = default;
            return TVal;
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
    public void Push(T item)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            if (Count == _array.Length)
                Array.Resize(ref _array, _array.Length + _array.Length / 4 * 3);
            _array[Count] = item;
            Interlocked.Increment(ref Count);
        });
    }
}

CustomArray.cs

Custom Array Class

using System;
using System.Collections;
using System.Collections.Generic;
public class CustomArray<T> : IEnumerable<T>
{
    private          T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public CustomArray(int cap)
    {
        _array = new T[cap];
        _maf   = new MonitorActionFunc();
        Count  = 0;
    }
    public int Length
    {
        get
        {
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () => _array.Length);
        }
    }
    public T this[int index]
    {
        get
        {
            var array   = _array;
            var idx     = index;
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () =>
            {
                if (idx > array.Length)
                    throw new Exception($"Error: Index {idx} out of range {array.Length}");
                return array[idx];
            });
        }
        set
        {
            var tmpThis = this;
            var idx     = index;
            tmpThis._maf.Lock(tmpThis, () =>
            {
                if (idx >= _array.Length)
                    Array.Resize(ref _array, idx + idx / 4 * 3);
                _array[idx] = value;
                Count++;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, _array.Length);
            Count = 0;
        });
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
    public T[] ToArray()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            return newtArray;
        });
    }
}

CustomToolTip.cs

Customer ToolTip Class

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
/// <summary>
///     A custom tooltip class which adds some things I would like to see. I originally wrote this to have access to the
///     tooltip text.
/// </summary>
public class CustomToolTip : ToolTip
{
    private readonly float[]    _GradientPositions;
    private readonly ColorBlend gradientBlender;
    private          Color      _gradientEndColor    = Color.DeepSkyBlue;
    private          Color      _gradientMiddleColor = Color.LightSkyBlue;
    private          Color      _gradientStartColor  = Color.LightSkyBlue;
    public CustomToolTip()
    {
        Font                      =  new Font("Arial Narrow", 9.75F, FontStyle.Bold, GraphicsUnit.Point, 0);
        _GradientPositions        =  new float[3];
        _GradientPositions[0]     =  0f;
        _GradientPositions[1]     =  .3f;
        _GradientPositions[2]     =  1f;
        gradientBlender           =  new ColorBlend(3) {Positions = _GradientPositions};
        gradientBlender.Colors[0] =  _gradientStartColor;
        gradientBlender.Colors[1] =  _gradientMiddleColor;
        gradientBlender.Colors[2] =  _gradientEndColor;
        OwnerDraw                 =  true;
        Popup                     += OnPopup;
        Draw                      += OnDraw;
    }
    /// <summary>
    ///     The font used in the drawing of the text.
    /// </summary>
    [Description("The font used in the drawing of the text.")]
    public Font Font
    {
        get;
        set;
    }
    /// <summary>
    ///     The background image used in the control.
    /// </summary>
    [Description("The background image used in the control.")]
    public Image BackgroundImage
    {
        get;
        set;
    }
    /// <summary>
    ///     Sets the color of the border
    /// </summary>
    [Description("Sets the color of the border")]
    public Color BorderColor
    {
        get;
        set;
    } = Color.DodgerBlue;
    /// <summary>
    ///     Enables or disables the drawing of the border
    /// </summary>
    [Description("Enables or disables the drawing of the border")]
    public bool EnableBorder
    {
        get;
        set;
    } = true;
    /// <summary>
    ///     Enables or disables the drawing of the Gradient Background
    /// </summary>
    [Description("Enables or disables the drawing of the Gradient Background")]
    public bool EnableGradientBackground
    {
        get;
        set;
    } = false;
    public string Text
    {
        get;
        set;
    } = "";
    /// <summary>
    ///     Sets the direction of the gradient
    /// </summary>
    [Description("Sets the direction of the gradient")]
    public LinearGradientMode GradientMode
    {
        get;
        set;
    } = LinearGradientMode.Vertical;
    /// <summary>
    ///     Sets the color of the start of the gradient
    /// </summary>
    [Description("Sets the color of the start of the gradient")]
    public Color GradientStartColor
    {
        get => _gradientStartColor;
        set
        {
            _gradientStartColor       = value;
            gradientBlender.Colors[0] = _gradientStartColor;
        }
    }
    /// <summary>
    ///     Sets the color of the middle of the gradient
    /// </summary>
    [Description("Sets the color of the middle of the gradient")]
    public Color GradientMiddleColor
    {
        get => _gradientMiddleColor;
        set
        {
            _gradientMiddleColor      = value;
            gradientBlender.Colors[1] = _gradientMiddleColor;
        }
    }
    /// <summary>
    ///     Sets the color of the end of the gradient
    /// </summary>
    [Description("Sets the color of the end of the gradient")]
    public Color GradientEndColor
    {
        get => _gradientEndColor;
        set
        {
            _gradientEndColor         = value;
            gradientBlender.Colors[2] = _gradientEndColor;
        }
    }
    /// <summary>
    ///     Set or Get the lower,center,upper bounds for the gradient brush
    /// </summary>
    [Category("Behavior")]
    [Description("Set or Get the lower,center,upper bounds for the gradient brush")]
    public float[] GradientPositions
    {
        get => _GradientPositions;
        set
        {
            _GradientPositions[0]     = value[0];
            _GradientPositions[1]     = value[1];
            _GradientPositions[2]     = value[2];
            gradientBlender.Positions = _GradientPositions;
        }
    }
    private void OnPopup(object sender, PopupEventArgs e)
    {
        var tt     = GetToolTip(e.AssociatedControl);
        var newstr = tt.Replace(@"\n", Environment.NewLine);
        e.ToolTipSize = newstr.MeasureText(Font, 1, 1);
    }
    private void OnDraw(object sender, DrawToolTipEventArgs e)
    {
        var fs = Font.GetFontSize();
        var g  = e.Graphics;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.InterpolationMode  = InterpolationMode.High;
        Text                 = e.ToolTipText;
        var newstr = e.ToolTipText.Replace(@"\n", Environment.NewLine);
        if (BackgroundImage == null)
            if (EnableGradientBackground)
            {
                var b = new LinearGradientBrush(e.Bounds, Color.Black, Color.Black, GradientMode) {InterpolationColors = gradientBlender};
                g.FillRectangle(b, e.Bounds);
            }
            else
            {
                g.FillRectangle(new SolidBrush(BackColor), new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
            }
        else
            g.DrawImage(new Bitmap(BackgroundImage, e.Bounds.Width, e.Bounds.Height), new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height));
        g.DrawString(newstr, Font, new SolidBrush(ForeColor), new PointF(e.Bounds.X + fs.Width / 2, e.Bounds.Y + fs.Height / 2));
        if (EnableBorder)
            g.DrawRectangle(new Pen(new SolidBrush(BorderColor), 1), new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1));
    }
}