这是一个帮助类,您可以将表单和控件类型传递给它,它将连接所有匹配的控件。在此示例中,所有按钮都已连接,因此您可以拖动它们。只需将“按钮”更改为您感兴趣的控件类型即可:
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>();
}
}
不同文件中的辅助类:
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;
}
}
请注意,我在 Load() 事件中使用“this”连接 Form1,但我也在 Click() 处理程序中为 Form2 的新实例演示它。
基于评论问题的附加帖子
根据您的 cmets,以下示例显示了 UserControl 内的按钮被连接起来以允许它们四处移动。 (我更改了 WireControlsOfType<> 方法以接受通用控件而不是 Form。) 默认 UserControl 属性中没有任何更改以允许这样做:
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>();
}
静态的 FormHelper 类是允许这种魔法的原因。它可以是它自己的类,不需要复制/关联任何 Forms/UserControls;实际上,它是独立于它们的,可以在自己的文件中。
如果您希望整个 UserControl 本身能够在其容器周围拖动,我在上面的帮助器类中添加了一个名为 WireUserControl() 的不同帮助器方法。所以下面的sn-p就是将多个UserControlA实例添加到panel1中,每一个都可以单独拖拽:
private void button1_Click(object sender, EventArgs e)
{
UserControlA ucA = new UserControlA();
panel1.Controls.Add(ucA);
ucA.WireUserControl();
}