【发布时间】:2010-01-12 07:29:44
【问题描述】:
当我在 ASPX 页面中为 Web 控件添加事件处理程序时 - 为什么它会传入发送方?与仅通过事件处理程序中的“ID”引用控件相比,使用 sender 有什么优势?
我可以查看我是否有一个单独的类来处理事件,并且多个控件将使用事件处理程序。但是如果我确定只有这个控件会处理这个事件,那么仅仅引用控件 ID 而不是将 sender 强制转换为我的对象类型是不是很糟糕?
谢谢!
【问题讨论】:
当我在 ASPX 页面中为 Web 控件添加事件处理程序时 - 为什么它会传入发送方?与仅通过事件处理程序中的“ID”引用控件相比,使用 sender 有什么优势?
我可以查看我是否有一个单独的类来处理事件,并且多个控件将使用事件处理程序。但是如果我确定只有这个控件会处理这个事件,那么仅仅引用控件 ID 而不是将 sender 强制转换为我的对象类型是不是很糟糕?
谢谢!
【问题讨论】:
您似乎只是从 ASP.NET 角度看待 .NET 事件。 .NET 事件模型在整个 .NET Framework 中被广泛使用,而不仅仅是 ASP.NET 页面和控件。
这种模式很灵活,允许任何(适当的)对象成为事件的起源,允许事件侦听器对引发它的对象“归零”以进行进一步处理。请记住,事件不仅需要有一个来源和一个侦听器/处理程序。
页面和控件都是对象,因此为了使其足够灵活,发件人键入对象。通过一些编程规则,应该能够定义可以引发该事件并将发送者对象转换回原始类型的已知类型。如果它是纯字符串控件 ID,则必须找到具有匹配 ID 的控件,这在充满大量控件层次结构的页面中可能并不容易。
【讨论】:
优点是您可以将相同的事件处理程序附加到多个控件的事件。由于您不知道在这种情况下引发事件的控件,您可以使用sender 参数来引用它。
【讨论】:
控件不需要有 ID,事件可以由多个控件引发。将对象设为发送者意味着您可以从没有 ID 的控件和一般对象中捕获事件。
【讨论】:
作为上述答案的补充,当您在Repeater 中创建按钮时,发件人可能会很方便。假设您为此迭代了 100 个订单或任何其他数据,并且您想要检查一个显示“OK”的按钮,您不希望能够按两次“OK”。
因此,在您的方法中,您可以将发件人用作:
Button b = sender as Button;
b.Enabled = false;
【讨论】:
您不会使用控件 ID 来引用引发事件的实例的另一个原因是事件系统跨越 .NET 框架,而不仅仅是 ASP.NET。引发事件的其他类型不一定有控件 ID(甚至可能根本不是控件)。
【讨论】:
菲利普,dtb
通过您的示例,我们正在进入事件处理的危险世界。 将发送者对象类型转换为其他类型实际上将知识“注入”到事件处理程序中,即这个事件处理程序正在被按钮调用。这使得事件处理程序无法被其他类型的控件或类使用。
共享事件处理程序听起来是个好主意,但根据我自己的经验(并查看其他人的代码),它更经常被滥用而不是使用。诚然,对于中继器,您没有太多选择。 我想说的是要小心你在实际事件处理程序中的代码,如果超过三行,请考虑创建一个函数。
吹毛求疵:
Button b = sender as Button;
if(b != null)
{
b.Enabled = false;
}
甚至更好:
Button clickedButton = sender as Button;
if(clickedButton != null)
{
clickedButton.Enabled = false;
}
问题:为什么 Enabled 属性被呈现为 Type ?
【讨论】: