Update: thanks to the suggestions of dacey Wayne mean Dudu boss and others, I have added the extension method version. The feeling of airborne troops like the expansion method
Data Binding seems to be an old thing in ASP. NET. But you know, you only need a small change to replace Eval, get rid of string dependencies and greatly improve performance.
First, add the following method to code behind:
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> protected virtual Object exphelper tentity, tresult > (func tentity, tresult > func)
{< br> var ITM = getdataitem ();
return func (tentity) ITM);
}
This sectionCodeIs the core secret. You can ignore what it is actually doing. In fact, each bound data item is intercepted and forced type conversion is performed.
Suppose we have defined the student class
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> Public class Student
{< br> Public string name { Get ; set ;}
Public int Age { Get ; set ;}
}
if you want to use a strong type of access to the student class instead of eval on the page, define a method to access the student.
Protected ObjectStu<Tresult>(Func<Student, tresult>Func)
{
ReturnExphelper<Student, tresult>(Func );
}
So we can bind data in this way on the page.
< Ul >
< ASP: Repeater ID = "Rptstudents" Runat = "Server" >
< Itemtemplate >
< Li > < % # Stu (_ => _. Name + "(" + _. Age + ")") % > </ Li >
</ Itemtemplate >
</ ASP: Repeater >
</ Ul >
This has four advantages:
- Compile-time detection
- Enjoy Smart Tips
- Stronger type conversion performance than eval reflection
- The content on the page is richer. As shown above, we can freely splice the desired string, very similar to MVC.
What's more amazing is that it supports multi-layer nesting. For example, we define a set group class and accessors for students, and then we can use nested repeater to display group information. CompleteProgramAs follows:
< % @ Page Language = "C #" Autoeventwireup = "True" % >
< Script Runat = "Server" >
Public class student
{
Public string name {Get; set ;}
Public int age {Get; set ;}
}
Public class group
{
Public ienumerable < Student > Students {Get; set ;}
}
Protected void page_load (Object sender, eventargs E)
{
// A group of students
VaR students = new [] {
New student {name = "Mike", age = 23 },
New student {name = "Jane", age = 12 },
New student {name = "Frank", age = 25 },
New student {name = "Susan", age = 32 },
};
Rptstudents. datasource = students;
// Two groups
VaR group0 = new group ();
Group0.students = students. Take (2 );
VaR group1 = new group ();
Group1.students = students. Skip (2). Take (2 );
Rptgroups. datasource = new [] {group0, group1 };
Databind ();
}
Protected virtual object exphelper < Tentity , Tresult > (Func < Tentity , Tresult > Func)
{
VaR ITM = getdataitem ();
Return func (tentity) ITM );
}
// Student accessors
Protected object Stu < Tresult > (Func < Student , Tresult > Func)
{
Return exphelper < Student , Tresult > (Func );
}
// Group accessors
Protected object GRP < Tresult > (Func < Group , Tresult > Func)
{
Return exphelper < Group , Tresult > (Func );
}
</ Script >
<! Doctype html >
< Html >
< Body >
< % -- Single Layer -- % >
< Ul >
< ASP: Repeater ID = "Rptstudents" Runat = "Server" >
< Itemtemplate >
< Li > < % # Stu (_ => _. Name + "(" + _. Age + ")") % > </ Li >
</ Itemtemplate >
</ ASP: Repeater >
</ Ul >
< % -- Nested -- % >
< Ul >
< ASP: Repeater ID = "Rptgroups" Runat = "Server" >
< Itemtemplate >
< Li >
< Ol >
< ASP: Repeater ID = "Repeater1" Runat = "Server" Datasource = '<% # GRP (_ => _. Students) %>' >
< Itemtemplate >
< Li > < % # Stu (_ => _. Name + "(" + _. Age + ")") % > </ Li >
</ Itemtemplate >
</ ASP: Repeater >
</ Ol >
</ Li >
</ Itemtemplate >
</ ASP: Repeater >
</ Ul >
</ Body >
</ Html >
PS
This article is a small invention that I have not previously written. It is mainly because there are very few people who know this method. I hope you can help test the performance. If you think it is appropriate, you can apply it to your actual work.
Update:
Thanks to the suggestions of dacey Wayne's mean Dudu boss and others.
I have added the extension method version. I like the concept of expansion.
Now, you only need to add a static help class and name it as you like.
Public Static Class Helper
{
Static Object Exphelper < Tentity, tresult > (Page, func < Tentity, tresult > Func)
{
VaR ITM = Page. getdataitem ();
Return Func (tentity) ITM );
}
Public Static Object Eval < T > ( This Page, func < T, Object > Func)
{
Return Exphelper < T, Object > (Page, func );
}
}
On the page, you can
<% # This. Eval<Student>(_ => _. Name + "(" + _. Age + ")") %>
- Note that this is required
- The extension method has good adhesion.
- No need for a parent class to define a common method
- The generic model provides multiple copies and is easy to see the type.
- In addition, refactor is supported. You can use Ctrl + R to change the attribute name.