10

我想我会问这个问题,看看为什么许多示例和人们更喜欢在 aspx 代码中使用内联数据绑定而不是在使用 WebForms 时实现 OnDataBinding 事件。

对于任何数据绑定控件(例如,Repeater、GridView 等),如果我需要执行任何不是开箱即用的内置操作(例如,我需要执行 Eval),我总是为字段级控件实现 OnDataBinding 方法。我看到的大多数示例都使用内联 <%# 语法在 aspx 页面中使用代码。

内联 ASP.NET 代码示例:

<asp:Literal ID="litExample" runat="server"
    Text='<%# Eval("ExampleField").ToString() %>' />

我喜欢如何做的例子:

在 aspx 中:

<asp:Literal ID="litExample" runat="server" 
    OnDataBinding="litExample_DataBinding" />

在代码隐藏 .cs 中:

protected void litExample_DataBinding(object sender, System.EventArgs e)
{
    Literal lit = (Literal)(sender);
    lit.Text = string.Format("{1} - {2}",
        Eval("ExampleField").ToString(),
        Eval("ExampleField2").ToString());
}

我个人更喜欢 codebehind 方法,因为它使我的 aspx 页面保持干净,而且我没有所有这些内联代码,下一个人只知道总是在 .cs 文件中查找代码更改。由于 HTML 只是占位符,代码绑定决定了实际控制的内容,因此这种方式也可以更好地保持表示和代码的分离。

现在这些都是非常基本的例子。该字段可以是您希望使用前导 0 格式化的整数或需要特定格式的 DateTime 等。它还可能需要各种操作和代码来获取应存储在“文本”属性中的最终值结束。

如果您使用内联代码,您在哪里画线并将其移动到代码隐藏?

无论哪种方式,都有哪些优点和缺点?

一个比另一个占用更多的开销吗?

编辑注意:我不是在谈论为仅在页面上的控件分配值,而是正在被数据绑定的控件,因为它存在于转发器模板或 gridview 项目模板等中......显然是坐在页面上的文字可以在代码中分配。

编辑注:我想我会收集更多的回应,特别是关于开销。大多数人不使用 OnDataBinding 事件吗?

4

5 回答 5

8

我更喜欢相反的情况。我更喜欢将我的代码隐藏限制在过程代码中,并将我的所有声明性代码保留在我的 Aspx 页面中。在上面的示例中,文字绝对是声明性的,因此(根据我的偏好)不属于代码隐藏。更强大的功能通常在我的代码隐藏中,我不希望我的开发人员在试图理解它时不得不筛选一堆初始化行而变得混乱。

于 2009-03-31T18:11:54.787 回答
6

它们之间几乎没有性能差异。数据绑定表达式被解析并编译成类似的东西

control.DataBinding += new EventHandler(ControlDataBinding);

并且

private void ControlDataBinding(object sender, EventArgs e) {
    control.Text = Eval("Field");
}

在这种情况下,不会重写 OnDataBinding 方法。执行基本 Control.OnDataBinding 方法,该方法引发 DataBinding 事件,从而导致执行上述代码。

当您覆盖 OnDataBinding 时,您只是在基本代码运行之前接管,并自己设置Text属性(例如)。


我不喜欢给出部分答案,但这次我会这样做,因为我认为它很整洁,而且它最近救了我:

我说数据绑定表达式被解析了。事实上,所有的标记都经过解析,生成了 C#、VB.NET 或任何语言的代码,并将它们编译成一个类。当页面被请求时,这个类的一个实例被创建,并开始它的生命。

您可以在磁盘上找到这些生成的代码文件,抱歉,我不记得在哪里。它们的有趣之处在于它们仍然可以作为代码工作。

例如,我最近设置了一些相当复杂的 Infragistics 网格,完成了所有格式设置,然后发现我需要能够在 rumtime 设置格式(以将正确的格式导出到导出的 Excel 文件中)。为此,我打开了源文件(所有网格都在单个用户控件中),并且能够将每个网格的配置提取到单独的一组方法中。

我能够使用 ReSharper 清理它们,将通用代码序列提取到基类中,并使用一种静态方法来设置每个网格。然后我可以调用它们进行初始设置,以及用于 Excel 导出的虚拟网格的设置。

于 2009-07-18T19:33:12.620 回答
1

我更喜欢 OnDataBinding 的方式。您可以通过对所有 OnDataBinding 调用使用“Databind”区域来保持代码隐藏的干净,并且可以通过从那里取出那些可怕的服务器端代码块来保持标记的干净。

我认为大多数人都使用内联方式,因为它更容易理解和实施。

于 2010-03-02T20:32:59.627 回答
0

实际上,我更喜欢将 aspx 用于您希望绑定的控件,例如 listview、gridview、repeater 和其他类似的控件。

对于其他控件,我会在代码隐藏中直接设置它们(作为我正在执行的过程的一部分,而不是为整个页面调用 literal.DataBind 或 DataBind)。如果它是一个用户/自定义控件,我希望调用者执行 DataBind,那么我将覆盖 DataBind 并设置值。

也就是说,我通常在代码隐藏之外有大量代码,并调用 ShowUser 之类的东西,在那里我将这些分配给控件(而不是设置属性,然后进行绑定,并为简单控件设置所有这些 eval) .

于 2009-03-31T18:29:59.563 回答
0

我同意菱角。我喜欢我的标记是干净的,并且我的所有 aspx/ascx 代码都驻留在我的代码隐藏文件(它所属的位置)中。

我只有一件事要补充。我不想在我的代码中乱扔我的每个数据绑定控件的 OnDataBinding() 事件。相反,我在嵌入可绑定控件(例如示例中的中继器)中的用户控件的 OnDataBinding() 事件中完成所有操作。

例如,在我的用户控件的代码隐藏中,您会发现:

protected override void OnDataBinding(EventArgs e)
{
    base.OnDataBinding(e);

    litExample.Text = Eval("ExampleField") + " - " + Eval("ExampleField2");
}

从这里您可以设置所有控件的属性或调用其他方法来设置它们。请注意,在我的示例中,我不需要像您在此处那样执行拳击:Literal lit = (Literal)(sender);

仅此一项就可以节省一些性能(当然是纳秒,但值得衡量)。在此处阅读“性能”部分:http: //msdn.microsoft.com/en-us/library/yz2be5wk%28v=vs.80%29.aspx

我也反对在我的代码中使用字符串。我会使用 const 字符串变量来定义“ExampleField”和“ExampleField2”,或者将它们设置为用户控件中的公共属性,然后可以由包含控件/页面根据数据对象的列名进行设置被束缚。这提供了更多的灵活性和控制的重复使用。

仅供参考:您不需要在 Eval 上调用 ToString(),因为此方法已经返回一个字符串。

于 2011-01-24T06:22:32.863 回答