代码之家  ›  专栏  ›  技术社区  ›  Kelsey

Ondatabinding vs inline:优点、缺点和开销

  •  10
  • Kelsey  · 技术社区  · 16 年前

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

    对于任何 数据绑定控件(如中继器、网格视图等) 如果我需要做任何非开箱即用的事情(例如,我需要做一个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" />
    

    在codebehind.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格式化的整数,也可以是需要特定格式等的日期时间。它还可以使用所有类型的操作和代码来获取应存储在末尾的“text”属性中的最终值。

    如果您使用的是内联代码,那么在哪里绘制行并将其移到codebehind?

    这样做的利弊是什么?

    一个人比另一个人承受更多的开销吗?

    编辑注释: 我说的不是为页面上的控件赋值,而是将数据绑定到的控件,因为它存在于转发器模板或GridView项模板等中…显然,一个文本位于一个页面上,您可以在代码中分配。

    编辑注释: 我想我会得到更多的回应,尤其是关于开销。大多数人不使用可绑定事件吗?

    5 回复  |  直到 16 年前
        1
  •  6
  •   John Saunders    16 年前

    它们之间的性能差别不大。数据绑定表达式被解析并编译为

    control.DataBinding += new EventHandler(ControlDataBinding);
    

    而且

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

    在这种情况下,不会重写OnDatabinding方法。将执行base control.ondatabinding方法,这将引发数据绑定事件,导致执行上述代码。

    当重写OnDatabinding时,只需在运行基代码之前接管,并开始设置 Text 拥有自己的财产(例如)。


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

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

    您可以在磁盘上找到这些生成的代码文件 对不起,我不记得在哪里 . 有趣的是,它们仍然作为代码工作。

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

    我能够用Resharper清理它们,将公共代码序列提取到一个基类中,并留下一个静态方法来设置每个网格。然后,我就可以为初始设置和用于Excel导出的虚拟网格的设置调用它们了。

        2
  •  8
  •   JoshJordan    16 年前

    我更喜欢相反的。我喜欢将代码保留在过程代码之后,并将所有声明性代码保留在ASPX页面中。在上面的示例中,文本是绝对声明性的,因此(依我的喜好)不属于代码隐藏。更健壮的功能通常都在我的代码后面,我不希望我的开发人员在试图理解它时,因为必须筛选一堆初始化行而变得混乱。

        3
  •  1
  •   caltrop    15 年前

    我更喜欢用你的方式进行数据绑定。对于所有的绑定调用,您可以使用“databind”区域来保持代码的整洁,并且您可以通过将那些可怕的服务器端代码块移出那里来保持标记的整洁。

    我认为大多数人都是以内联的方式进行的,因为这样更容易理解和实现。

        4
  •  0
  •   eglasius    16 年前

    实际上,我更喜欢将ASPX用于希望绑定的控件,如ListView、GridView、Repeater和其他类似的控件。

    对于其他控件,我将在codebehind中设置它们,但直接设置(作为我正在执行的过程的一部分,而不是为整个页面调用literal.databind或databind)。如果它是一个用户/自定义控件,我希望调用方执行数据绑定,那么我将重写数据绑定并设置值。

    也就是说,我通常在代码隐藏之外有大量的代码,并有一个类似ShowUser的调用,在那里我将这些分配放到控件中(而不是设置属性,然后进行绑定,并对简单控件进行所有评估)。

        5
  •  0
  •   MikeTeeVee ageektrapped    14 年前

    我同意菱角。我喜欢我的标记是干净的,所有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(),因为这个方法已经返回了一个字符串。