15

I need to have a MaskedTextBox in a ToolStrip, which isn't included by default, so I followed some advice I found online, and created custom control that inherits from ToolStripControlHost. What I've created works great when I'm running the application, but it really messes up the designer. By "messes up", I mean the custom control (Along with some others) disappear from the ToolStrip. Also I can no longer add new controls to the ToolStrip, and I can't select the existing controls on the ToolStrip to edit them.

Here's my class.

[DesignerCategory("code")]
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public partial class ToolStripMaskedTextBox : ToolStripControlHost
{
    public MaskedTextBox MaskedTextBox
    {
        get { return Control as MaskedTextBox; }
    }

    public ToolStripMaskedTextBox()
        : base(CreateControlInstance()) { }

    private static Control CreateControlInstance()
    {
        MaskedTextBox mtb = new MaskedTextBox();
        mtb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        mtb.MinimumSize = new System.Drawing.Size(100, 16);
        mtb.PasswordChar = '*';
        return mtb;
    }
}

Any help on what I might be doing wrong that's giving the designer a hard time would be appreciated.

Addition Info

Now when I open my class file in Visual Studio, I get a warning page with the following error:

Constructor on type 'System.Windows.Forms.ToolStripControlHost' not found. 

Addition Info 2

The problem only occurs after building the solution. I can get the designer working correctly by modifying the Form.Designer.cs file in even the smallest way. Like adding a single space. From there on out the designer will work fine. That is until I build the solution. Then the designer freezes up again. None of the controls on the form can be edited.

mellowsoon
  • 22,273
  • 19
  • 57
  • 75
  • Rebuild the solution, restart VS, and see if that helps. – SLaks Jan 13 '12 at 20:03
  • @SLaks - I've tied that, and sometimes it works, and sometimes it doesn't. The problem seems to be completely random. – mellowsoon Jan 13 '12 at 20:43
  • Have a look at `*.Designer.cs` after you saved the form and look if it is serialized correctly. – Olivier Jacot-Descombes Jan 17 '12 at 15:29
  • @Olivier - Which designer file should I be looking at? The one for the form the control has been placed on? Is there something odd I should be looking for? – mellowsoon Jan 17 '12 at 15:33
  • `MyForm.Designer.cs`. Check the `InitializeComponent` method of your form the control has been placed on. – Olivier Jacot-Descombes Jan 17 '12 at 15:36
  • @mellowsoon If your solution is currently set to Release mode, try setting it back to debug mode. – Kev Ritchie Jan 17 '12 at 15:56
  • It might also be worth checking this link http://stackoverflow.com/questions/2629090/vs-2008-designer-and-usercontrol – Kev Ritchie Jan 17 '12 at 16:03
  • The posted code works fine in VS2008 .NET 3.5. Can't reproduce any of those issues. Do you have any events hooked up related to the `ToolStrip` itself besides the clicking events? Try using your `ToolStrip` in an empty project, see if you can reproduce the problems there. – LarsTech Jan 17 '12 at 16:40
  • @Olivier - I don't see anything unusual in the designer file. What I found is when the designer is "stuck", modifying the designer file in any way (Even adding a single space) "unsticks" the designer. At least for a few builds. Then it gets stuck again. – mellowsoon Jan 17 '12 at 17:08
  • @Kev Ritchie - I really hope the answer isn't "The designer is just dumb" haha – mellowsoon Jan 17 '12 at 17:08
  • @mellowsoon :) - referring back to your configuration mode - are you set to release or debug? – Kev Ritchie Jan 17 '12 at 17:11
  • @LarsTech - I gave that a try, and I'm unable to reproduce the problem. Even if I add all the same controls to the form in my empty project, the problem doesn't occure. Hrm... – mellowsoon Jan 17 '12 at 17:35
  • @Kev Ritchie - I've tried it in both modes, and the results are the same. – mellowsoon Jan 17 '12 at 17:36
  • See if [this link][1] helps. Scroll to bottom. [1]: http://stackoverflow.com/questions/1667491/constructor-on-type-namespace-type-not-found – Peter Arandorenko Jan 23 '12 at 20:00
  • @mellowsoon Any new update on this? – Reza Aghaei Mar 12 '19 at 19:27

5 Answers5

11

According to the exception

Constructor on type 'System.Windows.Forms.ToolStripControlHost' not found. 

I found some information on the MSDN Forum.

This happends because the ToolStripControlHost class does not have a constructor with no parameter.

To solve this problem, you can create your own ToolStripControlHost with a none-parameter constructor and make the ToolStripMaskedTextBox inherited from your ToolStripControlHost. Try something like the following

//Declare a class that inherits from ToolStripControlHost.
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripMaskedTextBox : MyCustomToolStripControlHost
{
    // Call the base constructor passing in a MaskedTextBox instance.
    public ToolStripMaskedTextBox() : base(CreateControlInstance()) { }

    public MaskedTextBox MaskedTextBox
    {
        get
        {
            return Control as MaskedTextBox;
        }
    }


    private static Control CreateControlInstance()
    {
        MaskedTextBox mtb = new MaskedTextBox();
        mtb.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        mtb.MinimumSize = new System.Drawing.Size(100, 16);
        mtb.PasswordChar = '*';
        return mtb;
    }
}

public class MyCustomToolStripControlHost : ToolStripControlHost
{
    public MyCustomToolStripControlHost()
        : base(new Control())
    {
    }
    public MyCustomToolStripControlHost(Control c)
        : base(c)
    {
    }
}

This will fix the problem with your exception.

The Problem with the Forms Designer (ToolStripMaskedTextBox is not visible after running the app) is not solved but you can close the designer and open the file again.

Then you can go on without any problems.

Hope this helps

dknaack
  • 60,192
  • 27
  • 155
  • 202
  • This did solve the constructor problem, but unfortunately didn't solve the designer problem. – mellowsoon Jan 26 '12 at 20:25
  • That looks like a bug, even on the msdn forum no one knows how to solve this. I tried so many things too – dknaack Jan 26 '12 at 20:26
  • For me, the designer problem only occurred when the ToolStripMaskedTextBox control was located in the same project as the form I tried to use it on. When I put it into a separate project, the designer problem went away, without having to resort to using the System.Windows.Forms namespace as [Harry suggested](http://stackoverflow.com/a/20334693/520044). – takrl Jun 15 '16 at 07:59
1

I've used dknaack's solution, but placed MyCustomToolStripControlHost class in a separate file in System.Windows.Forms namespace. And...

First: it works - no exception. Then: my control is visible in designer as well, so it's a jackpot.

Community
  • 1
  • 1
Harry
  • 4,524
  • 4
  • 42
  • 81
0

FWIW: I also succeeded with dknaack's solution above, but only after I realized I was looking for the custom ToolStrip Control in the wrong place. The custom control doesn't show up in the Toolbox itself. Rather it shows up in the dropdown list of components under the "Add ToolStripButton" that appears on the ToolStrip when it is selected (in the designer).

0

I found a solution of designer's problem. https://dobon.net/vb/dotnet/control/tschdesigneravail.html#tips_comment (Japanese)

All you need is just make a class derived from ToolStrip and substitute it.

class DesignerFriendlyToolStrip : ToolStrip { }

var ts = new DesignerFriendlyToolStrip();
ts.Items.Add(toolStripMaskedTextBox);
form.Controls.Add(ts);

I don't know why this is effective. Anyone knows...?

hotaka
  • 1
  • 1
0

In this link, the answer was that the objects that implement "blah" interface must have a parameter-less constructor. Give it a try.

Community
  • 1
  • 1