Here's a helper class that you can pass a Form and a Control Type to and it will wire up all of the controls that match. In this example, all Buttons are wired up so you can drag them around. Just change "Button" to the type of control you're interested in:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.WireControlsOfType<Button>();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.Show();
f2.WireControlsOfType<Button>();
}
}
The helper class in a different file:
public static class FormHelper
{
public static void WireUserControl(this UserControl uc)
{
uc.MouseDown += _MouseDown;
uc.MouseMove += _MouseMove;
uc.MouseUp += _MouseUp;
}
public static void WireControlsOfType<T>(this Control sourceControl)
{
foreach(var ctl in sourceControl.RecursiveFindControlsByType<T>())
{
ctl.MouseDown += _MouseDown;
ctl.MouseMove += _MouseMove;
ctl.MouseUp += _MouseUp;
}
}
// Code by Jon Skeet: https://stackoverflow.com/a/2055946/2330053
public static IEnumerable<Control> RecursiveFindControlsByType<T>(this Control control)
{
foreach (Control c in control.Controls)
{
if (c is T)
{
yield return c;
}
if (c.Controls.Count > 0)
{
foreach (Control ctl in c.RecursiveFindControlsByType<T>())
{
yield return ctl;
}
}
}
}
private static bool mouseDown;
private static Point lastLocation;
private static void _MouseDown(object sender, MouseEventArgs e)
{
mouseDown = true;
lastLocation = e.Location;
}
private static void _MouseMove(object sender, MouseEventArgs e)
{
Control source = (Control)sender;
if (mouseDown)
{
source.Location = new Point((source.Location.X - lastLocation.X) + e.X, (source.Location.Y - lastLocation.Y) + e.Y);
}
}
private static void _MouseUp(object sender, MouseEventArgs e)
{
mouseDown = false;
}
}
Note that I'm wiring up Form1 in the Load() event with "this", but I'm also demonstrating it for a new instance of Form2 in the Click() handler.
Additional Post Based on Comment Questions
Based on your comments, here's an example showing the Buttons inside a UserControl being wired up to allow them to be moved around. (I changed the WireControlsOfType<>
method to accept generic control instead of Form.) Nothing was changed in the default UserControl properties to allow this:
private void button1_Click(object sender, EventArgs e)
{
panel1.Controls.Clear();
UserControlA ucA = new UserControlA();
ucA.Dock = DockStyle.Fill;
panel1.Controls.Add(ucA);
ucA.WireControlsOfType<Button>();
}
The static FormHelper class is what allows this magic. It can be its own class and does not need to be copied/associated with any of the Forms/UserControls; in fact, it's independent of them and can be in its own file.
If you want the entire UserControl itself to be able to be dragged around its container, I added in a different helper method called WireUserControl()
to the helper class above. So the snippet below is adding multiple instances of UserControlA to panel1, and each one could be dragged around separately:
private void button1_Click(object sender, EventArgs e)
{
UserControlA ucA = new UserControlA();
panel1.Controls.Add(ucA);
ucA.WireUserControl();
}