C# 如何处理ToolStripDropDown?
我在VS2012项目上运行了代码分析选项,它发现了以下内容: 拥有一次性字段的CA1001类型应为 “DataGridViewColumnSelector”上的一次性工具IDisposable 因为它会创建以下IDisposable类型的成员: “CheckedListBox”、“ToolStripDropDown”。如果“DataGridViewColumnSelector” 以前已发布,添加了实现IDisposable的新成员 对该类型的更改被视为对现有 消费者。DataGridColSelector DataGridViewColumnSelector.cs 我让我的类DataGridViewColumnSelector从IDisposable继承,我想知道在dispose方法中放什么 更新: 这是我的尝试。自从我将类密封后,代码分析就不再抱怨了。 我仍然不确定我是否“做对了”C# 如何处理ToolStripDropDown?,c#,winforms,idisposable,C#,Winforms,Idisposable,我在VS2012项目上运行了代码分析选项,它发现了以下内容: 拥有一次性字段的CA1001类型应为 “DataGridViewColumnSelector”上的一次性工具IDisposable 因为它会创建以下IDisposable类型的成员: “CheckedListBox”、“ToolStripDropDown”。如果“DataGridViewColumnSelector” 以前已发布,添加了实现IDisposable的新成员 对该类型的更改被视为对现有 消费者。DataGridColSel
公共密封类DataGridViewColumnSelector:IDisposable
{
私有DataGridView mDataGridView=null;
私有CheckedListBox mCheckedListBox;
专用工具条下拉列表mPopup;
public delegate void CustomRightClickDelegate(对象发送者,MouseEventArgs e);
公共事件CustomRightClickDelegate GridRightClickEvent;
///
///弹出窗口的最大高度
///
公共int最大高度=300;
///
///弹出窗口的宽度
///
公共整数宽度=200;
公共DataGridView DataGridView
{
获取{返回this.mDataGridView;}
设置
{
如果(this.mDataGridView!=null)this.mDataGridView.MouseDown-=this.mDataGridView\u MouseDown;
this.mDataGridView=值;
如果(this.mDataGridView!=null)this.mDataGridView.MouseDown+=this.mDataGridView\u MouseDown;
}
}
void mDataGridView_MouseDown(对象发送方,MouseEventArgs e)
{
if(e.Button==MouseButtons.Right)
{
if(this.mDataGridView.HitTest(e.X,e.Y).Type==DataGridViewHitTestType.ColumnHeader)
{
这个.mCheckedListBox.Items.Clear();
foreach(此.mDataGridView.Columns中的DataGridViewColumn c)
{
this.mCheckedListBox.Items.Add(c.HeaderText,c.Visible);
}
int PreferredHeight=(this.mCheckedListBox.Items.Count*20);
this.mCheckedListBox.Height=(PreferredHeight
您应该先调用dispose,然后再处理表单
还有。您的IDisposable
实现缺少一些重要的东西
1) 您应该确保没有订阅自定义事件的事件。这可能会给你的申请带来一个记忆障碍
//in dispose
GridRightClickEvent = null
2) 具有实施IDisposable
public sealed class DataGridViewColumnSelector : IDisposable
{
//removed: ~DataGridViewColumnSelector (){ Dispose(false); /*destructor*/ }
//class context omitted
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(disposing)
{
//kill the reference - do not dispose the object.
//it was *not* created here, os it should *not* be disposed here
mDataGridView = null;
//makes sure no outside object has a reference
//to the event - thus keeping it alive when it should be garbagecollected
GridRightClickEvent = null;
if(mCheckedListBox != null) mCheckedListBox.Dispose();
if(mPopup != null) mPopup.Dispose();
if(mControlHost != null) mControlHost .Dispose();
}
}
}
这取决于实现IDisposable的方式,以及创建新实例的频率。尝试显示您的代码以及如何使用它。您在方法中配置了正确的控件。我建议您在处理控件之前进行null检查,然后将其设置为null(只是为了确保GC真正意识到您不再需要此对象)。如果您真的不需要它,请不要调用GC方法,因为GC会自动工作。实现终结器(也称析构函数)不是最佳做法。只有当类存储非托管资源时才需要它,像这样的代码永远不会出现这种情况。当Dispose为false时,Dispose(bool)方法没有做任何有用的事情,这是犯此错误的最强烈迹象。就像你的片段一样。@HansPassant说得有道理。我编辑了代码exampel-删除析构函数下面是什么//在这里处理您的dispose?是
GridRightClickEvent=null;mCheckedListBox.Dispose();mPopup.Dispose()代码>@kirsteng我已经更新了我的示例,展示了如何处理Dispose方法。谢谢-什么是mControlHost?我的代码中没有这个。
public sealed class DataGridViewColumnSelector : IDisposable
{
//removed: ~DataGridViewColumnSelector (){ Dispose(false); /*destructor*/ }
//class context omitted
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(disposing)
{
//kill the reference - do not dispose the object.
//it was *not* created here, os it should *not* be disposed here
mDataGridView = null;
//makes sure no outside object has a reference
//to the event - thus keeping it alive when it should be garbagecollected
GridRightClickEvent = null;
if(mCheckedListBox != null) mCheckedListBox.Dispose();
if(mPopup != null) mPopup.Dispose();
if(mControlHost != null) mControlHost .Dispose();
}
}
}