简体   繁体   中英

.NET Custom Control (ToolStripControlHost) Wreaks Havoc on the Designer

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.

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

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.

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

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...?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM