在扩展方法中显示表单,并在表单关闭时删除未使用的资源和事件处理程序

时间:2016-07-08 10:27:06

标签: c# .net-4.0 extension-methods

我为DataTable构建了两个扩展方法。两者都在新窗口(窗体)内显示DataTable的内容。第一个使用attribute_id, start_dateShowDialog。以下是我的代码:

Show

我的问题是:如何在扩展方法中处理不需要的资源(在我的情况下,当表单关闭时) 使用public static class DataTableExtensions { public static void ShowDialog(this DataTable dataTable, string title = null, Size? size = null, DataGridViewCellFormattingEventHandler onCellFormatting = null) { using (var f = new Form()) { f.StartPosition = FormStartPosition.CenterScreen; f.FormBorderStyle = FormBorderStyle.SizableToolWindow; f.Size = size ?? new Size(500, 300); if (title != null) f.Text = title; using (var dgv = new DataGridView()) { dgv.ReadOnly = true; dgv.AutoGenerateColumns = true; dgv.Dock = DockStyle.Fill; dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dgv.MultiSelect = false; dgv.EnableHeadersVisualStyles = false; /*other settings*/ dgv.CellMouseEnter += (sender, e) => { var dataGridView = sender as DataGridView; if (dataGridView != null) dataGridView.InvalidateCell(e.ColumnIndex, e.RowIndex); }; dgv.CellMouseLeave += (sender, e) => { var dataGridView = sender as DataGridView; if (dataGridView != null) dataGridView.InvalidateCell(e.ColumnIndex, e.RowIndex); }; dgv.CellPainting += (sender, e) => { if (e.RowIndex != -1) return; var dataGridView = sender as DataGridView; if (dataGridView == null) { return; } Point cursorPosition = dataGridView.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); f.ShowDialog(); } } } [Obsolete("Use ShowDialog instead!")] public static void Show(this DataTable dataTable, string title = null, Size? size = null, DataGridViewCellFormattingEventHandler onCellFormatting = null) { 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 { dgv.ReadOnly = true; dgv.AutoGenerateColumns = true; dgv.Dock = DockStyle.Fill; dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dgv.MultiSelect = false; dgv.EnableHeadersVisualStyles = false; /*other settings*/ }; 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); f.Show(); } } 时,我在ShowDialog块内有所有内容,这样当不再需要时,会删除form和datagridview对象(如果我错了请纠正我) 第二种方法是使用using。我无法使用Show块,因此在表单关闭时如何删除所有事件处理程序和对象?
我应该担心吗?

我使用.NET 4.0,如果它改变了什么。

编辑:
基于@Hans Passant评论,我已经修改了我的代码。现在我有两个调用相同私有方法的扩展方法:

using

我已经为表格处置事件创建了事件处理程序:

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();
    }
}

所以现在当我关闭我的表格并处理它时我也处理了DataGridView 这足以清除窗体关闭时不需要的所有资源吗?

0 个答案:

没有答案