如何处理ToolStripDropDown?

时间:2013-04-22 04:43:55

标签: c# winforms idisposable

我在VS2012项目上运行了代码分析选项,它发现了以下内容;

  

CA1001拥有一次性领域的类型应该是   'DataGridViewColumnSelector'上的一次性实现IDisposable   因为它创建了以下IDisposable类型的成员:   'CheckedListBox','ToolStripDropDown'。如果'DataGridViewColumnSelector'   之前已经发布,添加了实现IDisposable的新成员   这种类型被认为是对现有的重大改变   消费者。 DataGridColSelector DataGridViewColumnSelector.cs

我创建了我的类,DataGridViewColumnSelector继承自IDisposable,我想知道在dispose方法中放入什么

更新:

这是我的尝试。自从我把课程封好后,Code Analysis就停止了抱怨。 我仍然不确定我“做得对”

    public sealed class DataGridViewColumnSelector  :IDisposable 
{
    private DataGridView mDataGridView = null;
    private CheckedListBox mCheckedListBox;
    private ToolStripDropDown mPopup;

    public delegate void CustomRightClickDelegate(object sender, MouseEventArgs e);

    public event CustomRightClickDelegate GridRightClickEvent;
    /// <summary>
    /// The max height of the popup
    /// </summary>
    public int MaxHeight = 300;
    /// <summary>
    /// The width of the popup
    /// </summary>
    public int Width = 200;

    public DataGridView DataGridView
    {
        get { return this.mDataGridView; }
        set
        {
            if (this.mDataGridView != null) this.mDataGridView.MouseDown -= this.mDataGridView_MouseDown;
            this.mDataGridView = value;
            if (this.mDataGridView != null) this.mDataGridView.MouseDown += this.mDataGridView_MouseDown;
        }
    }



    void mDataGridView_MouseDown(object sender, MouseEventArgs  e)
    {
        if (e.Button == MouseButtons.Right)
        { 

            if( this.mDataGridView.HitTest(e.X, e.Y).Type == DataGridViewHitTestType.ColumnHeader)
            {
                this.mCheckedListBox.Items.Clear();
                foreach (DataGridViewColumn c in this.mDataGridView.Columns)
                {
                    this.mCheckedListBox.Items.Add(c.HeaderText, c.Visible);
                }
                int PreferredHeight = (this.mCheckedListBox.Items.Count*20);
                this.mCheckedListBox.Height = (PreferredHeight < this.MaxHeight) ? PreferredHeight : this.MaxHeight;
                this.mCheckedListBox.Width = this.Width;
                this.mPopup.Show(this.mDataGridView.PointToScreen(new Point(e.X, e.Y)));
            }
            else
            {
                if (this.GridRightClickEvent != null)
                {
                    this.GridRightClickEvent.Invoke(sender, e);
                }

            }
        }
    }

    public DataGridViewColumnSelector()
    {
        this.mCheckedListBox = new CheckedListBox();
        this.mCheckedListBox.CheckOnClick = true;
        this.mCheckedListBox.ItemCheck += new ItemCheckEventHandler(this.mCheckedListBox_ItemCheck);

        ToolStripControlHost mControlHost = new ToolStripControlHost(this.mCheckedListBox);
        mControlHost.Padding = Padding.Empty;
        mControlHost.Margin = Padding.Empty;
        mControlHost.AutoSize = false;

        this.mPopup = new ToolStripDropDown();
        this.mPopup.Padding = Padding.Empty;
        this.mPopup.Items.Add(mControlHost);
    }

    public DataGridViewColumnSelector(DataGridView dgv)
        : this()
    {
        this.DataGridView = dgv;
    }

    void mCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e)
    {
        this.mDataGridView.Columns[e.Index].Visible = (e.NewValue == CheckState.Checked);
    }

    public void Dispose()
    {
        //http://stackoverflow.com/questions/6826958/c-toolstripdropdown-doesnt-dispose-destroyhandle
        // http://msdn.microsoft.com/en-au/library/b1yfkh5e%28v=vs.71%29.aspx 
        // Kirsten says I dont feel sure about what I am doing here.

        mCheckedListBox.Dispose(  );
        mPopup.Dispose(  );
        GC.SuppressFinalize(this);

    }
}

1 个答案:

答案 0 :(得分:1)

你打电话处理然后你的表格处理。

另外。您对IDisposable的实施缺乏一些重要的事情。

1)您应该确保没有订阅自定义事件的事件。这最终可能会给你的应用程序带来内存泄漏。

//in dispose
GridRightClickEvent = null

2)MSDN有实施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();

    }
  }
}