我为DataTable构建了两个扩展方法。两者都在新窗口(窗体)内显示DataTable的内容。第一个使用attribute_id, start_date
秒ShowDialog
。以下是我的代码:
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 这足以清除窗体关闭时不需要的所有资源吗?