title: GDI objects memory leak: Custom ToolStripControlHost within ContextMenuStrip is not disposing
body: <p>I have various custom context menus, based on ToolStripControlHost. They are wrapped inside ContextMenuStrip and placed in headers of DataGridView collumns (depending on some conditions) like this:</p>
  
  <pre><code>        if (this.DGV.Columns[DGVColname] != null)
          {
              ContextMenuStrip cstr = null;
              // there is always only one item in context menu
              // I tried disposing in different manners, this is an example of my efforts
              if (this.DGV.Columns[DGVColname].HeaderCell.ContextMenuStrip != null)
              {
                  cstr = this.DGV.Columns[DGVColname].HeaderCell.ContextMenuStrip;
  
                  if (cstr.Items[0] != null)
                  {
                      cstr.Items[0].Dispose();
                      cstr.Items.Clear();
                  }
              }
              else
              {
                  cstr = new ContextMenuStrip();
                  cstr.Opened += new EventHandler(cstr_Opened);
              }
  
              TextBoxToolStrip tsHost = new TextBoxToolStrip();
  
              tsHost.Size = new System.Drawing.Size(172, 20);
              tsHost.TextChanged += new EventHandler(myToolStrip_TextChanged);
  
              cstr.ShowCheckMargin = false;
              cstr.ShowImageMargin = false;
              cstr.Margin = new Padding(0);
              cstr.Padding = new Padding(0);
              cstr.Items.Add(tsHost);
  
              cstr.MaximumSize = new Size(tsHost.Width + 10, tsHost.Height + 10);
              cstr.Size = cstr.MaximumSize;
              cstr.LayoutStyle = ToolStripLayoutStyle.Flow;
  
              DGV.Columns[DGVColname].HeaderCell.ContextMenuStrip = cstr;
          }
  </code></pre>
  
  <p>Despite calling dispose and/or setting whatever I can get my hands on to nulls GDI object count for my app's proccess still increases in a steady manner. I have 20 collumns with menus in my DataGridView, and I get +30 or +34 (exactly) every time the code is called.</p>
  
  <p>TextBoxToolStrip in this example extends ToolStripControlHost and contains a single TextBox:</p>
  
  <pre><code>   public class TextBoxToolStrip : ToolStripControlHost
      {
          // .... some string or bool Properties here ....
  
          public TextBox TextBoxControl
          {
              get { return Control as TextBox; }
          }
  
          public TextBoxToolStrip()
              : base(new TextBox())
          {
              this.TextBoxControl.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
              | System.Windows.Forms.AnchorStyles.Right)));
  
              this.TextBoxControl.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
              this.TextBoxControl.Location = new System.Drawing.Point(0, 3);
              this.TextBoxControl.ReadOnly = false;
              this.TextBoxControl.Font =
                  new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
  
              this.TextBoxControl.Size = new System.Drawing.Size(172, 20);
              this.Size = new System.Drawing.Size(172, 20);
  
              this.TextBoxControl.TabIndex = 0;
              this.TextBoxControl.TextAlign = System.Windows.Forms.HorizontalAlignment.Left;
  
              this.MouseHover += new EventHandler(TextBoxToolStrip_Enter);
  
              this.AutoSize = false;
              this.TextBoxControl.PreviewKeyDown += new PreviewKeyDownEventHandler(TextBoxPreviewKeyDown);
              this.TextBoxControl.KeyDown += new KeyEventHandler(TextBoxControl_KeyDown);
          }
  
          protected override void OnSubscribeControlEvents(Control control)
          {
              base.OnSubscribeControlEvents(control);
  
              TextBox tb = control as TextBox;
  
              if (tb != null)
              {
                  tb.TextChanged += new EventHandler(OnTextChanged);
              }
          }
  
          protected override void OnUnsubscribeControlEvents(Control control)
          {
              base.OnUnsubscribeControlEvents(control);
  
              TextBox tb = control as TextBox;
  
              if (tb != null)
              {
                  tb.TextChanged -= OnTextChanged;
              }
          }
  
          private void TextBoxToolStrip_Enter(object sender, EventArgs e)
          {
              this.Focus();
          }
  
          private void TextBoxPreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
          {
              if (e.KeyCode == Keys.Menu)
                  e.IsInputKey = true;
          }
  
          private void TextBoxControl_KeyDown(object sender, KeyEventArgs e)
          {
              TextBox txb = sender as TextBox;
              ToolStripDropDown tsd = (ToolStripDropDown)txb.Parent;
  
              if (e.KeyCode == Keys.Enter)
              {
                  tsd.Close();
              }
          }
  
          /// &lt;summary&gt;
          /// Expose TextChanged event
          /// &lt;/summary&gt;
          public new event EventHandler TextChanged;
  
          private void OnTextChanged(object sender, EventArgs e)
          {
              if (TextChanged != null)
              {
                  TextChanged(this, e);
              }
          }
  </code></pre>
  
  <p><strong>QUESTION:</strong></p>
  
  <p>How can I properly dispose of the context menu?</p>