C# OnDataBinding 与内联:优点、缺点和开销

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/702343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 14:03:11  来源:igfitidea点击:

OnDataBinding vs Inline: pros, cons and overhead

c#asp.netcoding-stylecode-behind

提问by Kelsey

I thought I would ask this question to see why many examples and people prefer to use inline databinding in the aspx code vs implementing an OnDataBinding event when using WebForms.

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

For any databound control (eg. Repeater, GridView, etc)I always implement the OnDataBinding method for field level controls if I need to do anything that isn't built in out of the box (eg. I need to do an Eval). Most examples I see have the code right in the aspx page using the inline <%# syntax.

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

Example of inline ASP.NET code:

内联 ASP.NET 代码示例:

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

Example of how I prefer to do it:

我更喜欢这样做的示例:

In the aspx:

在aspx中:

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

In the codebehind .cs:

在代码隐藏 .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());
}

I personally prefer the codebehind method because it keeps my aspx pages clean and I don't have all this inline code all over the place and the next guy just knows to always look in the .cs files for code changes. The seperation of presentation and code is also maintained better this way as the HTML is place holders only and the codebind is determining what is actually being put in control.

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

Now these are very basic examples. The field could be a integer that you want to format with leading 0s or a DateTime that needs a specific format etc. It could also take all sort of manipulation and code to get the finally value that should be stored in the 'Text' property at the end.

现在这些是非常基本的例子。该字段可以是一个整数,你想用前导 0 或一个需要特定格式的 DateTime 等进行格式化。它也可以采取各种操作和代码来获取应存储在“文本”属性中的最终值结束。

Where do you draw the line and move it to the codebehind if you are using inline code?

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

What are the pros and cons for doing it either way?

这样做的优缺点是什么?

Does one take more overhead than the other?

一个比另一个花费更多的开销吗?

Edit Note:I am not talking about assigning a value to a control that is just on the page but one that is being databound to because it exists in a repeater template or gridview item template etc... Obviously a literal sitting on a page you can just assign in code.

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

Edit Note:I thought I would gather more response, especially with regards to the overhead. Do most people NOT use the OnDataBinding events?

编辑注意:我想我会收集更多的回应,尤其是在开销方面。大多数人不使用 OnDataBinding 事件吗?

采纳答案by John Saunders

There's little performance difference between them. A data binding expression is parsed and compiles out to something like

它们之间的性能差异很小。数据绑定表达式被解析并编译成类似

control.DataBinding += new EventHandler(ControlDataBinding);

and also

并且

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

In this case, the OnDataBinding method is not overridden. The base Control.OnDataBinding method is executed, which raises the DataBinding event, causing the above code to execute.

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

When you override OnDataBinding, you're simply taking over before the base code is run, and get to set the Textproperty yourself (for example).

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



I dislike giving out partial answers, but I'll do it this time because I think it's neat, and it saved me recently:

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

I said that the data binding expression are parsed. In fact, all of the markup is parsed, code in C#, VB.NET or whatever language is generated, and this is them compiled into a class. When the page is requested, an instance of this class is created, and it begins its life.

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

You can locate these generated code files on disk sorry, I don't remember where. The interesting thing about them is that they still work, as code.

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

For instance, I recently had some fairly complex Infragistics grids set up, had all the formatting complete, and then found that I needed to be able to set the formatting at rumtime (to get the correct format into exported Excel files). In order to do this, I opened the source file (all grids were in a single user control) and was able to extract the configuration of each grid into a separate group of methods.

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

I was able to clean them up with ReSharper, extract common code sequences into a base class, and was left with one static method to set up each grid. I was then able to call them both for the initial setup, and for the setup of the dummy grid used for Excel export.

我能够使用 ReSharper 清理它们,将常见的代码序列提取到一个基类中,并且只剩下一个静态方法来设置每个网格。然后,我可以在初始设置和用于 Excel 导出的虚拟网格的设置中调用它们。

回答by JoshJordan

I much prefer the opposite. I prefer to keep my code-behind limited to procedural code, and keep all my declarative code in my Aspx page. In your example above, the literal is absolutely declarative and therefore (by my preference) would not belong in code-behind. Much more robust functionality generally goes in my code-behind, and I don't want my developers to be cluttered by having to sift through a bunch of initialization lines when trying to understand it.

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

回答by eglasius

Actually I prefer to use the aspx for controls that you would expect to Bind, like listview, gridview, repeater and other similar controls.

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

For the other controls, I would set them in the codebehind, but directly (as part of the process I am doing, instead of calling the literal.DataBind or DataBind for the whole page). If it is an user/custom control, that I expect the callers to do a DataBind, then I would override DataBind and set the values.

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

That said, I usually has plenty of code outside the codebehind, and have a call to something like ShowUser, where I put those assignments to controls (instead of setting a property, then doing a bind, and having all those evals for simple controls).

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

回答by caltrop

I prefer it your way with OnDataBinding. You can keep your codebehind clean by using a "Databind" region for all the OnDataBinding calls, and you can keep your markup clean by getting those horrible server-side code blocks out of there.

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

I think most people do it the inline way because it's easier to understand and to implement.

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

回答by MikeTeeVee

I agree with caltrop. I like my markup to be clean and all my aspx/ascx code to reside in my code-behind files (where it belongs).

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

I only have one thing to add. I prefer not to litter my code with OnDataBinding() events wired for each of my databound controls. Instead I do it all in the OnDataBinding() event of the User Control that is being embedded in the bindable-control (such as the repeater in your sample).

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

For example, in my User Control's code-behind you would find:

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

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

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

From here you can set the properties of all your controls or call other methods to set them. Notice how, in my example, I didn't need to perform the boxing like you did here: Literal lit = (Literal)(sender);

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

That alone should save you on some performance (nanoseconds of course, but something worth measure). Read the section "Performance" here: http://msdn.microsoft.com/en-us/library/yz2be5wk%28v=vs.80%29.aspx

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

I am also at war with using strings in my code. I would have either used const string variables to define "ExampleField" and "ExampleField2" or set them up as public properties in the User Control that could then be set by the containing control/page based on the column name of the data object it will be bound against. This affords more flexibility and re-use of the control.

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

FYI: You don not need to call ToString() on Eval, as this method already returns a string.

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