2013-04-22 2 views
0

내 VS2012 프로젝트에서 코드 분석 옵션을 실행했으며 다음을 발견했습니다. 'CheckedListBox', '으로 ToolStripDropDown을'일회용 필드를 소유ToolStripDropDown을 어떻게 처리합니까?

CA1001 유형은 다음으로 IDisposable 유형의 구성원을 만들기 때문에 일회용 가 'DataGridViewColumnSelector' 에는 IDisposable을 구현해야합니다. 'DataGridViewColumnSelector' 이 이전에 배송 된 경우 IDisposable 을 구현하는 새 멤버를이 유형에 추가하면 기존 소비자의 주요 변경 사항으로 간주됩니다. DataGridColSelector DataGridViewColumnSelector.cs

나는 내 수업을 만들어, DataGridViewColumnSelector이는 IDisposable에서 상속 및 처분 방법에 넣어 무엇인지 궁금

업데이트 :

가 여기 내 시도이다. 수업을 봉쇄 한 이후로 코드 분석이 중단되었습니다. 나는 여전히

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

    } 
} 
+0

, 얼마나 자주 새 인스턴스를 만듭니다 위치 : implemeting위한 가장 좋은 방법이있다. 코드를 표시하고 사용 방법을 시험해보십시오. –

+0

메서드에 올바른 컨트롤을 배치하고 있습니다. 난 당신이 컨트롤을 처분하기 전에 널 체크를 제안하고 나중에 null로 설정 (그냥 GC가 정말로 당신이 더 이상이 개체가 필요하지 않습니다 인식하고 있는지 확인). 당신이 정말로 필요하지 않으면, GC 메서드를 호출하면 GC가 자동으로 작동합니다. – wonko79

답변

1

그런 다음 양식 처분하는 처분 전화 놈이야 내가 "바로 그 일을"하고 확실하지 않다.

또한. IDisposable 구현에 필수적인 요소가 부족합니다.

1) 맞춤 이벤트에 가입 한 이벤트가 없는지 확인해야합니다. 결국 응용 프로그램에 메모리 누출이 생길 수 있습니다.

//in dispose 
GridRightClickEvent = null 

2) MSDN는`IDisposable`을 구현하는 방법에 따라 달라 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(); 

    } 
    } 
} 
+0

파이널 라이저 (일명 소멸자)를 구현하는 것은 모범 사례가 아니므로 **. 클래스가 관리되지 않는 리소스를 저장할 때만 필요합니다. 이렇게하면 절대 이와 같은 코드를 사용하지 않아야합니다. 이 실수를 가장 잘 표시하는 것은 Dispose (bool) 메서드가 * disposing *이 false 일 때 유용하지 않은 경우입니다. 너의 발췌 문장 에서처럼. –

+0

@HansPassant 그것이 의미가 있습니다. 코드 exampel을 편집하여 소멸자를 제거했습니다. –

+0

아래에서 처리 할 내용은 // 여기에서 처리하십시오. 'GridRightClickEvent = null; mCheckedListBox.Dispose(); mPopup.Dispose(); ' –

관련 문제