In fact, the Eval method is TemplateControl, while the System. web. UI. page and System. web. UI. userControl inherits from TemplateControl, so we can directly call a method on Page and UserControl.
The Page. Eval method can help us better write data binding expressions. In the ASP. NET 1. x era, the general form of data binding expressions is:
<% # DataBinder. Eval (Container, "DataItem. Name") %>
In ASP. NET 2.0, the same code can be written as follows:
<% # Eval ("Name") %>
How is ASP. NET 2.0 implemented? First, we will study the Eval method. By reflecting the source code of the. NET work 2.0 class library, we can see that this method is implemented as follows:
Protected internal object Eval (string expression)
{
This. CheckPageExists ();
Return DataBinder. Eval (this. Page. GetDataItem (), expression );
}
We don't have to worry about the first line. This is to check whether there is a Page object during the call. If not, an exception will be thrown.
The key is the second line:
Return DataBinder. Eval (this. Page. GetDataItem (), expression );
Page. GetDataItem () is also a newly added method in 2.0. It is used to replace Container. DataItem in ASP. NET 1. x.
It seems that the GetDataItem () method is hard to understand the Eval principle. The implementation of GetDataItem is also very simple:
Public object GetDataItem ()
{
If (this. _ dataBindingContext = null) | (this. _ dataBindingContext. Count = 0 ))
{
Throw new InvalidOperationException (SR. GetString ("Page_MissingDataBindingContext "));
}
Return this. _ dataBindingContext. Peek ();
}
We noticed that there is an internal object _ dataBindingContext, which is a Stack type by checking the source code. So he has the Peek method. This piece of code is easy to understand. First, judge whether the Stack is instantiated, and then determine whether there are any elements in the Stack. If the Stack is not instantiated or has no elements, an exception is thrown. Finally, return the elements at the top of the stack.
ASP. NET 2.0 uses a Stack to save the so-called DataItem. We soon found the method for compressing and popping the element for this Stack: Control. DataBind:
Protected virtual void DataBind (bool raiseOnDataBinding)
{
Bool flag1 = false; // The use of this flag is easily introduced in the context. If DataItem is used to press the stack, the stack is output later.
If (this. IsBindingContainer) // determines whether the control is a data-bound container. In fact, it is used to determine whether the control class implements INamingContainer.
{
Bool flag2;
Object obj1 = DataBinder. GetDataItem (this, out flag2); // this method is used to determine whether the control has the DataItem attribute and obtain it.
If (flag2 & (this. Page! = Null) // if the control has DataItem
{
This. Page. PushDataBindingContext (obj1); // press DataItem to stack. PushDataBindingContext is to call the Push method of _ dataBindingContext.
Flag1 = true;
}
}
Try
{
If (raiseOnDataBinding) // you can check whether the DataBinding event is triggered.
{
This. OnDataBinding (EventArgs. Empty );
}
This. dataBindChildren (); // bind data to the Child control. If the control has a DataItem, The DataItem is pushed to the top of the stack. In this way, the Eval or GetDataItem method is called in the Child control, the DataItem you just pressed will be taken out.
}
Finally
{
If (flag1) // if there is a stack, it will pop up now.
{
This. Page. PopDataBindingContext (); // PopDataBindingContext is the Pop method that calls _ dataBindingContext
}
}
}
So far, we have a full understanding of the working principles of the GetDataIten and Eval methods in ASP. NET 2.0. Next time I plan to study the new Bind syntax in ASP. NET 2.0.
If you provide Bind syntax materials and make good suggestions, you can give scores as appropriate. There are very few groups such as up and top, and no score is given.
Efficiency:Undoubtedly, the efficiency of Container conversion is the highest. Eval eventually calls the DataBinder. Eval method, and DataBinder. Eval uses reflection to obtain data, which is obviously not as efficient as data conversion.
We can compare various methods:
(Type) Container. DataItem). Property
This method is the most efficient, because there is no reflection.
The second is:
(Type) GetDataItem (). Property
The reason for the low efficiency of this method is that there is one more Stack of Peek operations. Of course, in fact, this difference can be ignored.
Finally:
Eval or DataBinder. Eval, both methods use reflection to search for attributes or indexer members, reducing efficiency.
Another noteworthy problem is that all controls that implement the INamingContainer interface should implement the IDataItemContainer interface, because in the Control. if you find that the control implements the INamingContainer interface during DataBind, you will try to find its DataItem. If the control does not implement IDataItemContainer, DataBinder. the GetDataItem method uses reflection to check whether the control has an attribute member called DataItem. Obviously, this is not what we want to see.
In fact, ASP. NET also has a tag interface: INonBindingContainer. controls that implement the INamingContainer interface can choose to implement this command at the same time to run ASP. NET does not look for DataItem, but unfortunately, I do not know what Microsoft is for, this interface is internal ......
In fact, you don't need to pay too much attention to efficiency. The Eval expression looks good. Even if you have so much attention to efficiency, GeDataItem is also a good choice. Undoubtedly, the efficiency of Container conversion is the highest. Eval eventually calls the DataBinder. Eval method, and DataBinder. Eval uses reflection to obtain data, which is obviously not as efficient as data conversion.
We can compare various methods:
(Type) Container. DataItem). Property
This method is the most efficient, because there is no reflection.
The second is:
(Type) GetDataItem (). Property
The reason for the low efficiency of this method is that there is one more Stack of Peek operations. Of course, in fact, this difference can be ignored.
Finally:
Eval or DataBinder. Eval, both methods use reflection to search for attributes or indexer members, reducing efficiency.
Another noteworthy problem is that all controls that implement the INamingContainer interface should implement the IDataItemContainer interface, because in the Control. if you find that the control implements the INamingContainer interface during DataBind, you will try to find its DataItem. If the control does not implement IDataItemContainer, DataBinder. the GetDataItem method uses reflection to check whether the control has an attribute member called DataItem. Obviously, this is not what we want to see.
In fact, ASP. NET also has a tag interface: INonBindingContainer. controls that implement the INamingContainer interface can choose to implement this command at the same time to run ASP. NET does not look for DataItem, but unfortunately, I do not know what Microsoft is for, this interface is internal ......
In fact, you don't need to pay too much attention to efficiency. The Eval expression looks good. Even if you have so much attention to efficiency, GeDataItem is also a good choice.
* ************************ (DataRowView) Container. dataItem) ["XX"] is more efficient than <% # DataBinder. eval (Container, "DataItem. name ") %> much higher.
<% # Eval ("Name") %> is more than <% # DataBinder. Eval (Container, "DataItem. Name") %> ). Efficiency can be imagined.
Of course, there may also be some optimizations in 2.0.
* ******************* See http: // localhost/QuickStartv20/aspnet/doc/data/templates. aspx # twowaybind
Bidirectional data binding
Like the DetailsView control, FormView supports automatic Update, Insert, and Delete operations through its associated data source control. To define the input UI for editing or inserting operations, you can define EditItemTemplate or InsertItemTemplate while defining ItemTemplate. In this template, you will bind the input controls (such as TextBox, CheckBox, or DropDownList) to the fields of the data source. However, data binding in these templates uses the "bidirectional" Data Binding syntax, allowing FormView to extract the value of the input control from the template for transfer to the data source. These data bindings use the new Bind (fieldname) syntax instead of Eval.
Important: controls that use Bind syntax for data binding must have the ID attribute.
<Asp: FormView performanceid = "objectperformance1" DataKeyNames = "PhotoID" runat = "server">
<EditItemTemplate>
<Asp: TextBox ID = "CaptionTextBox" Text = '<% # Bind ("Caption") %> 'runat = "server"/>
<Asp: Button Text = "Update" CommandName = "Update" runat = "server"/>
<Asp: Button Text = "Cancel" CommandName = "Cancel" runat = "server"/>
</EditItemTemplate>
<ItemTemplate>
<Asp: Label Text = '<% # Eval ("Caption") %> 'runat = "server"/>
<Asp: Button Text = "Edit" CommandName = "Edit" runat = "server"/>
</ItemTemplate>
</Asp: FormView>
When performing an update or Insert operation on the GridView or DetailsView, if BoundField is defined for the column or field of the control, the GridView or DetailsView is responsible for creating the input UI in Edit or Insert mode, so that it can automatically extract these input values to pass back to the data source. Because the template contains any user-defined UI control, you must use the bidirectional data binding syntax, in this way, FormView and other templated controls can know which control values should be extracted from the template for update, insert, or delete operations. In EditItemTemplate, you can still use the Eval syntax to bind data that is not passed back to the data source. In addition, like DetailsView and GridView, FormView supports retaining the original values of primary key fields (even if these fields are not rendered) using the DataKeyNames attribute to pass back the update/insert operation.
FormView supports using the DefaultMode attribute to specify the default template to be displayed. However, by default, FormView starts and presents the ItemTemplate in ReadOnly mode. To enable the UI for converting from ReadOnly mode to Edit or Insert mode, you can add a Button control to the template and set its CommandName attribute to Edit or New. You can add a button in EditItemTemplate that sets CommandName to Update or Cancel to submit or stop an Update operation. Similarly, you can add a button with CommandName set to Insert or Cancel to submit or stop the Insert operation.
The following example shows a FormView that defines ItemTemplate and EditItemTemplate. ItemTemplate contains controls bound using Eval (one-way), while EditItemTemplate contains a TextBox Control bound using Bind statements in two-way. The primary key field (PhotoID) uses the DataKeyNames attribute for round-trip in the view State. FormView contains command buttons for switching between templates.
C # Two-Way Databinding in a FormView Edit Template
By using the TemplateField added to the Columns or Fields set, GridView and DetailsView also support templated UI. TemplateField supports using ItemTemplate, EditItemTemplate, and InsertItemTemplate (only DetailsView) to specify the field UI in different rendering modes of these controls. Like the FormView example above, two-way binding in EditItemTemplate or InsertItemTemplate allows the GridView or DetailsView to extract values from the controls in these templates. A common purpose of TemplateField is to add a validators control to EditItemTemplate for declarative verification of the GridView or DetailsView operation. The following example shows an example of this method. For more information about the authentication controls available in ASP. NET, see the "verify form input controls" section in this tutorial.
C # Validation in a GridView Edit Template
Another purpose of TemplateField is to customize the input control, which is used to input the values of the GridView or DetailsView columns/fields. For example, you can place the DropDownList control in the EditItemTemplate of TemplateField to allow selection from the predefined Value List. The following example demonstrates this method. Note: In this example, DropDownList is bound with its own data source control to dynamically obtain the value of this list.
C # DropDownList in a GridView Edit Template