1

I've got a really weird problem with ToolStripPanel.Join and I've been searching on Google and SO for some clue as to what I'm doing wrong but I can't figure it out. Basically, when I use ToolStripPanel.Join, the first ToolStrip that I add doesn't appear at all in the ToolStripPanel but all other ToolStrips that I join will appear. Before I get too far into the details, let me first say that I'm using C# and VS 2010 and .NET 4 and, just for some context, I'm trying to use a ToolStripPanel on a user control which is inside of a custom dll that we made so that we could reuse these user controls in other forms.

I was previously using a ToolStripContainer but I decided to switch out to use a ToolStripPanel since we only really needed the top panel of the ToolStripContainer; I didn't see the point of using a ToolStripContainer. Since I couldn't find a ToolStripPanel control in the Toolbox, I decided to add it myself in the Designer.cs file. Here's how I did it:

private ToolStripPanel tsPanel;
<--Other code here-->
private void InitializeComponent()
{
    this.tsPanel = new System.Windows.Forms.ToolStripPanel();
    <--Other code here-->
    // 
    // tsPanel
    // 
    this.tsPanel.Dock = System.Windows.Forms.DockStyle.Top;
    this.tsPanel.Location = new System.Drawing.Point(0, 0);
    this.tsPanel.Margin = new System.Windows.Forms.Padding(3);
    this.tsPanel.Name = "tsPanel";
    this.tsPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
    this.tsPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
    this.tsPanel.Size = new System.Drawing.Size(1000, 0);
    <--Other code here-->
    // 
    // MFDesigner
    // 
    this.BackColor = System.Drawing.Color.Gainsboro;
    <--Add other controls to UC Controls collection-->
    this.Controls.Add(this.tsPanel);
    this.ForeColor = System.Drawing.Color.Black;
    this.Name = "MFDesigner";
    this.Size = new System.Drawing.Size(1000, 670);
    this.Load += new System.EventHandler(this.MultiFormatDesignerControl_Load);
    this.Resize += new System.EventHandler(this.MFDesigner_Resize);
    this.pnlToolbox.ResumeLayout(false);
    this.pnlProperties.ResumeLayout(false);
    this.ResumeLayout(false);
    this.PerformLayout();
}

Then, in the user control's constructor, I have:

public MFDesigner()
{
    InitializeComponent();
    <--Other code here-->
    ToolStripButton[] openSaveButtonArr = new ToolStripButton[]{
        //The createToolStripButton method creates toolstrip buttons using some simple
        //parameters.
        createToolStripButton("Open", Images.CmdOpen, new EventHandler(this.OnOpen), "Open saved file"),
        createToolStripButton("Save", Images.CmdSave, new EventHandler(this.OnSaveToDisk), "Save to disk")
    };
    ToolStrip openSaveToolStrip = new ToolStrip(openSaveButtonArr);
    tspanel.Join(openSaveToolStrip);
    <--Other code here-->
}

Since we're creating tool strips and adding them to the toolstrippanel in code, I can't see what it looks like in the designer for the user control. So, I build the dll and I go over to another form in a separate project that consumes the user control from the dll and when the form opens, there is no toolstrip; it simply doesn't appear. Here's the weird thing, though. If I add just one more toolstrip to the panel, the second toolstrip will appear:

public MFDesigner()
{
    InitializeComponent();
    <--Other code here-->
    ToolStripButton[] openSaveButtonArr = new ToolStripButton[]{
        //The createToolStripButton method creates toolstrip buttons using some simple
        //parameters.
        createToolStripButton("Open", Images.CmdOpen, new EventHandler(this.OnOpen), "Open saved file"),
        createToolStripButton("Save", Images.CmdSave, new EventHandler(this.OnSaveToDisk), "Save to disk")
    };
    ToolStrip openSaveToolStrip = new ToolStrip(openSaveButtonArr);
    tspanel.Join(openSaveToolStrip, 1);
    ToolStripButton[] openSaveButtonArr2 = new ToolStripButton[]{
        createToolStripButton("Open2", Images.CmdOpen, new EventHandler(this.OnOpen), "Open saved rpx file 2"),
        createToolStripButton("Save2", Images.CmdSave, new EventHandler(this.OnSaveToDisk), "Save to disk 2")
    };
    ToolStrip openSaveToolStrip2 = new ToolStrip(openSaveButtonArr2);
    tsPanel.Join(openSaveToolStrip2, 1);
    <--Other code here-->
}

In the code above, the first toolstrip that I create will not appear, but the second one (openSaveToolStrip2) will appear. Incidentally, if I just use the Join overload Join(toolStrip) for both of the toolstrips, nothing appears. Also, if I add toolstrips to other rows, i.e. tsPanel.Join(toolstrip3, 2) or tsPanel.Join(toolstrip4, 3), the toolstrips will appear.

It seems like, for some inexplicable (for me, at least) reason, the first toolstrip that I add never appears but all subsequent toolstrips do. As a workaround, I've been just creating a dummy toolstrip, adding it, then adding all of my real toolstrips. This feels pretty hacky so I'd love to figure out why this is happening. I've tried to follow the documentation on MSDN but I must still be missing something because I can't imagine a bug like this not getting fixed.

Does anybody know what might be going wrong here?

greyseal96
  • 880
  • 7
  • 23
  • Not sure if this is relevant or not, but just in case... This project was upgraded from VS 2008 and .NET 3.5 to VS 2010 and .NET 4. – greyseal96 Oct 13 '14 at 23:50

1 Answers1

0

Screenshot of running application with all tool strips inside the tool strip panel

Running application with all tool strips inside the tool strip panel

I took your code and removed stray members so that I could compile, or stuff that was not relevant for your issue (these for instance: //private Panel pnlToolbox; //private Panel pnlProperties;). I created the runtime tool strips and joined them to the panel, same as you did. I also provided my own implementation of createToolStripButton since you did not. The third toolstrip uses Image.FromStream and web resources since I lacked the local ones. With or without images I had no malfunction whatsoever ...

Complete example below:

public partial class MFDesigner : Form {
    private ToolStripPanel tsPanel;
    //private Panel pnlToolbox;
    //private Panel pnlProperties;        

    public MFDesigner ( )
    {
      InitializeComponent();
      //
      // first toolstrip
      //
      ToolStripButton tsbOpen = new ToolStripButton("Open", null, new EventHandler(this.OnOpen), "Open saved file");
      ToolStripButton tsbSave = new ToolStripButton("Save", null, new EventHandler(this.OnSaveToDisk), "Save to disk");
      ToolStripButton[] openSaveButtonArr = new ToolStripButton[] { tsbOpen, tsbSave };
      ToolStrip openSaveToolStrip = new ToolStrip(openSaveButtonArr) { CanOverflow = true };
      this.tsPanel.Join(openSaveToolStrip);    
      //
      // second toolstrip
      //
      ToolStripButton tsbOpen2 = createToolStripButton("Open2", null, new EventHandler(this.OnOpen), "Open saved file");
      ToolStripButton tsbSave2 = createToolStripButton("Save2", null, new EventHandler(this.OnSaveToDisk), "Save to disk");
      ToolStripButton[] openSaveButtonArr2 = new ToolStripButton[] { tsbOpen2, tsbSave2 };
      ToolStrip openSaveToolStrip2 = new ToolStrip(openSaveButtonArr2) { CanOverflow = true };
      this.tsPanel.Join(openSaveToolStrip2, 1);      
      //
      // third toolstrip
      //
      WebClient wc = new WebClient();
      byte[] bytes = wc.DownloadData("http://my.crestron.eu/images/icons/ico_folder_open.png");
      // You must keep the stream open for the lifetime of the Image.
      MemoryStream msOpen = new MemoryStream(bytes);
      System.Drawing.Image imgOpen = System.Drawing.Image.FromStream(msOpen);

      bytes = wc.DownloadData("http://www.njrussians.com/images/save_ico.png");
      MemoryStream msSave = new MemoryStream(bytes);
      System.Drawing.Image imgSave = System.Drawing.Image.FromStream(msSave);
      ToolStripButton tsbOpen3 = createToolStripButton("Open3", imgOpen, new EventHandler(this.OnOpen), "Open saved file");
      ToolStripButton tsbSave3 = createToolStripButton("Save3", imgSave, new EventHandler(this.OnSaveToDisk), "Save to disk");
      ToolStripButton[] openSaveButtonArr3 = new ToolStripButton[] { tsbOpen3, tsbSave3 };
      ToolStrip openSaveToolStrip3 = new ToolStrip(openSaveButtonArr3) { CanOverflow = true };
      this.tsPanel.Join(openSaveToolStrip3, 2);     

    }

    ToolStripButton createToolStripButton (string text, Image i, EventHandler eh, string name)
    {
      return new ToolStripButton(text, i, eh, name);
    }

    void MFDesigner_Resize (object sender, System.EventArgs e) { }

    void MFDesigner_Load (object sender, System.EventArgs e) { }

    void OnOpen (object target, EventArgs e) { }

    void OnSaveToDisk (object target, EventArgs e) { }

    #region Windows Form Designer generated code
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose (bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
      }
      base.Dispose(disposing);
    }

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent ( )
    {
      this.tsPanel = new System.Windows.Forms.ToolStripPanel();
      this.SuspendLayout();
      // 
      // tsPanel
      // 
      this.tsPanel.Dock = System.Windows.Forms.DockStyle.Top;
      this.tsPanel.Location = new System.Drawing.Point(0, 0);
      this.tsPanel.Margin = new System.Windows.Forms.Padding(3);
      this.tsPanel.Name = "tsPanel";
      this.tsPanel.Orientation = System.Windows.Forms.Orientation.Horizontal;
      this.tsPanel.RowMargin = new System.Windows.Forms.Padding(3, 0, 0, 0);
      this.tsPanel.Size = new System.Drawing.Size(984, 0);
      // 
      // MFDesigner
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
      this.BackColor = System.Drawing.Color.Gainsboro;
      this.ClientSize = new System.Drawing.Size(984, 632);
      this.Controls.Add(this.tsPanel);
      this.ForeColor = System.Drawing.Color.Black;
      this.Name = "MFDesigner";
      this.Text = "MFDesigner";
      this.Load += new System.EventHandler(this.MFDesigner_Load);
      this.Resize += new System.EventHandler(this.MFDesigner_Resize);
      this.ResumeLayout(false);
      this.PerformLayout();    
    }    


    #endregion    
  }
andrei.ciprian
  • 2,895
  • 1
  • 19
  • 29
  • I thank you for taking the time to get all this mocked up. Unfortunately, it's not super helpful because it basically confirms that something weird is definitely happening but it doesn't give any clue as to what might be causing the problem. – greyseal96 Oct 13 '14 at 18:35
  • I just noticed that you are using a form for your test. Not sure if I stated it above or not, but I'm laying all of this out in a user control in one dll project and then I'm putting that user control onto a form in another project. Do you think that that makes a difference? – greyseal96 Oct 14 '14 at 23:36
  • >"You aren't even sure about having details...you didn't even bother to read your original post." Not sure why you felt it was necessary to tack that snarky rude part onto the end of your comment. You could have simply addressed my question about having a user control in one dll and using it in a form in another project. BTW, I thought that it might sound nicer to say "Not sure if I stated it above or not..." rather than, "Hey, not sure if you read my original post because you're using a form, which doesn't reproduce my original conditions, and you're not addressing why you chose to do that." – greyseal96 Oct 16 '14 at 01:04
  • In spite of that, though, I really am grateful that you took the time to respond and offer help. – greyseal96 Oct 16 '14 at 01:05
  • Take as much debris as you can out of the code and share it, if that's not possible provide more detail on the form/user control initialization. Is the ToolStrip nested inside the user control consumed by the form? That is not clear... – andrei.ciprian Oct 16 '14 at 01:55