C#:将派生类作为一个泛型参数传递

标签 c# winforms oop

我最近开始学习更多关于事件/委托(delegate)以及类扩展的知识。

我想通过向名为 SetDraggable() 的 Windows Form 控件添加一个 extension 方法来将我学到的知识付诸实践,该方法又使用 MouseDownMouseMove 事件来移动控件。

一切正常,除了它只适用于特定控件的想法——在我的例子中,一个 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;
            }
        }

    }
}

可以看出,我需要特定的控件才能调用鼠标事件——我无法从 parentSystem.Windows.Forms 访问这些事件.

所以我的问题仍然存在——是否有一个概念允许程序员通常将所有派生类作为参数传递。我基本上是在尝试避免为每个控件复制粘贴以下代码,并希望将其推广到所有派生自 System.Windows.Forms 的类。

据我所知,这个想法的主要缺陷是我假设所有派生类都会有我需要的事件;然而,由于以委托(delegate)的形式存在类似的功能,我希望有人可以权衡涉及对象或参数的情况。

最佳答案

父类不是 System.Windows.Forms,它只是命名空间。实际的父类是 Control,您当然可以使用它 :) 也可以使用泛型方法,但不是必须的。

理想情况下,您还希望避免使用这些静态字段,因为可能有多个并发的可拖动对象; SetControlDraggable 方法中的闭包会工作得更好:

public static void SetControlDraggable(this Control control)
{
  Point mouseDownLocation = Point.Empty;

  control.MouseDown += (s, e) =>
    {
      if (e.Button == MouseButtons.Left) mouseDownLocation = e.Location;
    }
  control.MouseUp += (s, e) =>
    {
      if (e.Button == MouseButtons.Left)
      {
        control.Left = e.X + control.Left - mouseDownLocation.X;
        control.Top = e.Y + control.Top - mouseDownLocation.Y;
      }
    }
}

关于C#:将派生类作为一个泛型参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42955375/

相关文章:

oop - 为什么没有为不同的返回类型定义方法重载?

c# - 在单元测试中使用 httpcontext

c# - 运算符 '?' 不能应用于类型 'T' 的操作数 (2)

c# - 通过获取文件路径来排列 TreeView?

c# - 将整数添加到 ListView 进行排序

JavaScript - "this"指向 Window 而不是对象

java - 如何在 java 或 c# 中强制执行 ddd 聚合?

c# - asp.net:如何防止用户多次发布相同的数据

c# - TableAdapter.Update(DataSet) 使西里尔字母在 dgv 中显示为问号

python - 面向对象编程Python : Where to instantiate Cassandra and elasticsearch cluster?