0

I am trying to extend the FlowLayoutPanel class in Visual Studio to give it some functionality that it does not currently have. I am having issues extending it in such a manner that I can then select it in the toolbox and add it to another form.

The three methods I have tried are to simply just create a new class that subclasses FlowLayoutPanel, also one that subclasses and then calls the : base() constructor. When the application is built the subclass shows up in the toolbox but when I go to add it to a form it says "Failed to load toolbox item, it will be removed from the toolbox."

I have also tried to add a new UserControl which I change its base class to FlowLayoutPanel instead of UserControl. After commenting out a line in the designer about AutoScaleMode I can then build the application. Once I try to place the panel from the toolbox I receive the same error above.

How can I properly subclass FlowLayoutPanel in Visual Studio so that I can use it from the toolbox?

EDIT:

Here is the entirety of my code, I added the OnPaint override based on amura.cxg's answer and I still receive the same error.

I have cleaned, rebuilt, closed, and reopened VisualStudio to no avail. I have also copied amura.cxg's code exactly and used it, again the same issue.

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace UserInterface.SubclassedControls
{
    class TestLayoutPanel : FlowLayoutPanel
    {
        public TestLayoutPanel() /* : base() */
        {

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }
    }
}

EDIT2:

I have made my class public and again cleaned, rebuilt, closed, and opened Visual Studio and still have the same issue. I have also tried to add the control to a "brand new" form with the same results.

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading.Tasks;
using System.Collections.Generic;

namespace UserInterface.SubclassedControls
{
    public class TestLayoutPanel : FlowLayoutPanel
    {
        public TestLayoutPanel() /* : base() */
        {

        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
        }
    }
}

EDIT3:

So as a sanity check I started a new VS project and subclassed FlowLayoutPanel and added it to the default Form1. I then went back to my current project and tried to create a simple new form class to see if my current form was having issues, but I still received the same error when trying to add the subclass FLP to it. I then tried a UserControl that I made prior and have successfully added to other forms, which is now "broken" giving the same error message.

So what Project settings or Visual Studio settings could be preventing me from using these controls?

KDecker
  • 6,928
  • 8
  • 40
  • 81
  • My crystal ball says that you need to use the DesignMode property. So you can prevent your code from throwing an exception at design time. Where to put it nobody can tell you when you don't post a snippet. Start up VS again and attach the debugger to the first instance to diagnose exceptions. – Hans Passant Sep 17 '15 at 14:02
  • What do you mean by "attach the debugger to the first instance"? The first instance of Visual Studio? Could you explain how to do that? – KDecker Sep 17 '15 at 14:46
  • You need to add the `public` access modifier to your class. Without it it's assumed to be `internal` and can't be seen by the designer. Check the edit to my answer – amura.cxg Sep 17 '15 at 14:47
  • That makes sense, I have added it. I still have the same issue. I again cleaned, rebuilt, closed, and reopened Visual Studio... – KDecker Sep 17 '15 at 14:50
  • Also is there a specific way I should restart the designer? The only way I can think of is to close and reopen VS. – KDecker Sep 17 '15 at 14:56
  • Hmmm, so it's not a code issue. Check out this [SO Answer](http://stackoverflow.com/questions/3446429/how-to-put-a-usercontrol-into-visual-studio-toolbox) – amura.cxg Sep 17 '15 at 14:56
  • I have tried every single answer on that page... // Time for lunch, when I return I will try a completely new VS project to see if that works.. – KDecker Sep 17 '15 at 15:07
  • Ok so I have easily managed to subclass FLP in a new project. I have also tried to create a new simple `form` in my current project and try to add a subclass of FLP to, but I get the same error. // I have also found that other custom controls such as a `UserControl` I have used from the toolbox before now do not work. // What project/VS settings could keep me from using these controls from the toolbox? – KDecker Sep 17 '15 at 16:22
  • Hmm, so I recently also changed the target architecture of my project from x86 to x64. I faintly remember something from a past project about "32 bit controls".. So I decided to change my target architecture to Any CPU. I can now add the controls to the form. Can anyone explain what I might've faintly remembered? // Also, changing to AnyCpu causes issue with 64-bit dlls that I have to include in my project, is there a way to target x64 and still use the controls? – KDecker Sep 17 '15 at 16:28

1 Answers1

1

You should post your code so we can see exactly what you've tried as you may be missing something. Make sure you've built your project and try closing the re-opening the designer.

Below is an example of all you should (keyword) need to do to get it to work. I tested this in VS 2013 and the CustomFlowLayout control showed up in my ToolBox after a rebuild

public class CustomFlowLayout : FlowLayoutPanel
{
    public CustomFlowLayout()
    {
        //Do things here!
    }

    public int MyCustomProperty { get; set; }

    //Not needed to make anything work, added to show the code is working
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        StringFormat format = new StringFormat()
        {
            LineAlignment = StringAlignment.Center,
            Alignment = StringAlignment.Center
        };

        e.Graphics.DrawString("It works! Wooooo..!", 
            SystemFonts.DefaultFont, 
            SystemBrushes.ControlText, 
            new Rectangle(0, 0, this.Width, this.Height), 
            format);
    }
}

After building what shows up in the ToolBox

After dropping it into a window

Edit

Looks like you were missing the public keyword. When you don't specify the access modifier it uses the default, which is Internal. Below is a corrected version.

public class TestLayoutPanel : FlowLayoutPanel
{
    public TestLayoutPanel() /* : base() */
    {

    }
}
amura.cxg
  • 2,348
  • 3
  • 21
  • 44