0

I have a TabPage with several panels and nested controls inside them like comboboxes, maskedtextboxes, textboxes, buttons, datagridviews etc.

My goal is to clone this TabPage with all of it's controls and their respective event handlers (like comboBox_SelectedIndexChanged, textBox_TextChanged, button_Click etc) into a new TabPage.

For that purpose I created a class TabPageCloner as follow:

using System;
using System.Windows.Forms;
using System.Reflection;

public class TabPageCloner
{
    public static TabPage CloneTabPage(TabPage originalTab)
    {
        // Create a new TabPage instance
        TabPage newTab = new TabPage(originalTab.Text);

        // Clone each control on the original tab
        foreach (Control control in originalTab.Controls)
        {
            Control clonedControl = CloneControl(control);
            newTab.Controls.Add(clonedControl);
        }

        return newTab;
    }

    private static Control CloneControl(Control originalControl)
    {
        // Create an instance of the original control's type
        Control newControl = (Control)Activator.CreateInstance(originalControl.GetType());

        // Copy basic properties
        newControl.Text = originalControl.Text;
        newControl.Size = originalControl.Size;
        newControl.Location = originalControl.Location;
        newControl.Anchor = originalControl.Anchor;
        newControl.Dock = originalControl.Dock;

        // Clone any nested controls (for containers like Panels, GroupBoxes, etc.)
        if (originalControl.HasChildren)
        {
            foreach (Control childControl in originalControl.Controls)
            {
                Control clonedChild = CloneControl(childControl);
                newControl.Controls.Add(clonedChild);
            }
        }

        // Clone event handlers
        CloneEvents(originalControl, newControl);

        return newControl;
    }

    private static void CloneEvents(Control originalControl, Control newControl)
    {
        // Use reflection to clone event handlers
        EventInfo clickEvent = originalControl.GetType().GetEvent("Click");
        if (clickEvent != null)
        {
            FieldInfo eventField = typeof(Control).GetField("EventClick", BindingFlags.Static | BindingFlags.NonPublic);
            object eventDelegate = eventField?.GetValue(originalControl);

            if (eventDelegate is EventHandler eventHandlers)
            {
                foreach (Delegate handler in eventHandlers.GetInvocationList())
                {
                    clickEvent.AddEventHandler(newControl, handler);
                }
            }
        }

    }
}

I am using it in my main form like this:

    TabPage clonedTabPage = TabPageCloner.CloneTabPage(MyOriginalTabPage);
    tabControl1.TabPages.Add(clonedTabPage);
    tabControl1.SelectedTab = clonedTabPage;

The problem is that event handlers not cloning at all. Also comboBox items not cloning at all.

What am I missing?

2
  • 3
    Have you considered building a UserControl that contains all the child Controls you have on that TabPage, so you just need to create a new instance of this UC (all the functionality is then already contained in the new instance), then eventually pass the data sources using a custom public method? Commented Oct 12, 2024 at 8:01
  • That is a great approach. It allows for easier cloning and better organization of code. Thanks a lot for your help! Commented Oct 12, 2024 at 8:16

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.