最近我开始学习有关事件/委托与类的扩展。
通过添加一个名为 SetDraggable()
的扩展方法到 Windows 窗体控件,我想把我所学的应用到实践中。该方法使用 MouseDown
和 MouseMove
事件来移动控件。
一切都很顺利,但问题是它只适用于特定的控件 - 在我的情况下,是一个 Button
。
namespace Form_Extensions
{
public static class Extensions
{
private static System.Windows.Forms.Button StubButton;
private static Point MouseDownLocation;
public static void SetDraggable(this System.Windows.Forms.Button b)
{
b.MouseDown += b_MouseDown;
b.MouseMove += b_MouseMove;
StubButton = b;
}
private static void b_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
static void b_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
StubButton.Left = e.X + StubButton.Left - MouseDownLocation.X;
StubButton.Top = e.Y + StubButton.Top - MouseDownLocation.Y;
}
}
}
}
如下所示,我需要特定的控件来调用鼠标事件——我不能从父类System.Windows.Forms中访问这些事件。
所以我的问题仍然存在——有没有一种概念允许程序员通用地传递所有派生类作为参数。我基本上正在尝试避免为每个控件复制粘贴以下代码,并希望将其泛化为所有从System.Windows.Forms派生的类。
据我所知,这个思路的主要缺陷是我假设所有派生类都将具有我需要的事件;然而,由于委托在函数形式上存在类似的事情,我希望有人能够权衡涉及对象或参数的情况。
System.Windows.Forms
,那只是命名空间。父类是Control
,你当然可以使用它 :) 使用泛型方法也是可能的,但并不是必要的。理想情况下,你还应该避免使用那些静态字段,因为可能会有多个并发的可拖动对象;在SetControlDraggable
方法中使用闭包会更好。或者直接使用sender
,这才是它的真正用途 :) - Luaan