I've build two extension methods, that allows me to show DataTable inside window.Below is my code:public static class DataTableExtensions{    public static void Show(this DataTable dataTable, string title = null, Size? size = null, DataGridViewCellFormattingEventHandler onCellFormatting = null)    {        Show(dataTable, title, size, onCellFormatting,false);    }    public static void ShowDialog(this DataTable dataTable, string title = null, Size? size = null, DataGridViewCellFormattingEventHandler onCellFormatting = null)    {        Show(dataTable,title,size,onCellFormatting,true);    }    private static void Show(DataTable dataTable, string title, Size? size, DataGridViewCellFormattingEventHandler onCellFormatting, bool modal)    {        var f = new Form        {            StartPosition = FormStartPosition.CenterScreen,            FormBorderStyle = FormBorderStyle.SizableToolWindow,            Size = size ?? new Size(500, 300)        };        if (!string.IsNullOrWhiteSpace(title))        {            f.Text = title;        }        else if (!string.IsNullOrWhiteSpace(dataTable.TableName))        {            f.Text = dataTable.TableName;        }        var dgv = new DataGridView        {            ReadOnly = true,            AutoGenerateColumns = true,            Dock = DockStyle.Fill,            SelectionMode = DataGridViewSelectionMode.FullRowSelect,            MultiSelect = false,            EnableHeadersVisualStyles = false            /*other settings*/        };        f.Disposed += (sender, args) =>        {            Debug.WriteLine(Disposed);            if(!dgv.IsDisposed) dgv.Dispose();        };        dgv.CellMouseEnter += (sender, e) =>        {            dgv.InvalidateCell(e.ColumnIndex, e.RowIndex);        };        dgv.CellMouseLeave += (sender, e) =>        {            dgv.InvalidateCell(e.ColumnIndex, e.RowIndex);        };        dgv.CellPainting += (sender, e) =>        {            if (e.RowIndex != -1) return;            Point cursorPosition = dgv.PointToClient(Cursor.Position);            if (e.CellBounds.Contains(cursorPosition))            {                using (var brush = new LinearGradientBrush(e.CellBounds, Color.White, Color.Black, LinearGradientMode.Vertical))                {                    e.Graphics.FillRectangle(brush, e.CellBounds);                }            }            else            {                using (var brush = new LinearGradientBrush(e.CellBounds, Color.Red, Color.Green, LinearGradientMode.Vertical))                {                    e.Graphics.FillRectangle(brush, e.CellBounds);                }            }            //paint rest, we only want to override background and borders            e.Paint(e.CellBounds, DataGridViewPaintParts.ContentForeground | DataGridViewPaintParts.ContentBackground | DataGridViewPaintParts.Border);            e.Handled = true;        };        dgv.DataSource = dataTable;        if (onCellFormatting != null)            dgv.CellFormatting += onCellFormatting;        f.Controls.Add(dgv);        if (modal)            f.ShowDialog();        else            f.Show();    }}I've asked similar question on StackOverflow, but because I've cleared cod a bit not I'd like to get it's review.In previous version I had only ShowDialog function, I was able to have everything inside using blocks, but now I want to have two functions, so I can't use using blocks.Most important thing is proper resource disposing. I'm not that advanced so I can't tell what parts can be problematic and figure a way to change/optimize them.
DataTable extension methods and proper disposing of unneeded resources
c#;winforms;memory optimization;.net datatable