在ASP.NET 2.0中操作数据:在GridView控件中使用TemplateField

英文原版  |   本教程的代码(C#)   |   翻译目录   |   原文目录

导言

GridView是由一组字段(Field)组成的,它们都指定的了来自DataSource中的什么属性需要用到自己的输出呈现中。最简单的字段类型是BoundField,它仅将数据简单的显示为文本。其他的字段类型使用交互HTML元素(alternate HTML elements)来显示数据。比如说,CheckBoxField将被呈现为一个CheckBox,其选中状态由某特定数据字段的值来决定;ImageField则将某特定数据字段呈现为一个图片,当然,这个数据字段中应该放的是图片类型的数据。超级链接和按钮的状态取决于使用HyperLinkFieldButtonField字段类型的数据字段的值。

 

虽然CheckBoxFieldImageFieldHyperLinkFieldButtonField考虑到了数据的交互视图,但它们仍然有一些相关的格式化的限制。CheckBoxField只可以显示为一个单个的CheckBox,而一个ImageField则只可以显示为一张图片。如果某个字段要显示一些文本、复选框、图片还有一些其他基于不同数据的东西的时候,我们要做什么?或者说,如果我们需要使用除了CheckBoxImageHyperLink以及Button之外的Web控件来显示数据时,我们该怎么办?此外,BoundField只能显示一个单独的数据字段。如果我们想要在一个GridView列中显示两个或者更多的数据字段的值的时候该怎么办呢?

 

为了适应这样的一个复杂的情况,GridView提供了使用模板来进行呈现的TemplateField。模板可以包括静态的HTMLWeb控件以及数据绑定的代码。此外,TemplateField还拥有各种可以用于不同情况的页面呈现的模板。比如说,ItemTemplate是默认的用于呈现每行中的单元格的,而EditItemTemplate则用于编辑数据时的自定义界面。


在本节教程中,我们将解释如何使用TemplateField来更加高级的自定义GridView控件。在上一节教程中,我们看到了如何使用DataBound和RowDataBound事件处理方法来自定义基于数据的格式化。另一个办法就是在模板中调用一个格式化方法。在本节中,我们就会看到这种技术。

 

在本节中,我们将使用一些TemplateField来自定义雇员信息的呈现。特别的,我们将列出所有的雇员,但我们将会把雇员的姓和名字放在一列中,把他们的雇佣日期放在一个Calendar控件中,还将用一个状态列来表明他们来到公司有多久了。

 
aspnet_tutorial12_TemplateFieldsInGV_cs_figure01.gif

图一:使用三个TemplateField来自定义信息的显示方式

 

第一步:将数据绑定到GridView

当你需要使用一些TemplateField来自定义显示时,我发现最简单的就是先创建一个仅包含BoundField的GridView控件,然后添加一些TemplateField,如果需要的话,也可以将某些BoundField直接转换成TemplateField。好了,让我们开始本节教程吧。首先,通过设计器往页面上添加一个GridView控件,并将一个返回雇员信息的ObjectDataSource绑定到它上面。这些步骤将创建一个带有一些BoundField的GridView,这些BoundField对应雇员信息中不同的字段。

 

打开GridViewTemplateField.aspx,并从工具箱中拖一个GridView到设计器上。从GridView的智能标签(smart tag)上选择并添加一个新的调用EmployeesBLL 类的GetEmployees()方法的ObjectDataSource控件。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure02.gif

图二:添加一个新的调用GetEmployees()方法的ObjectDataSource控件

用这种方式绑定GridView将会自动的为雇员信息的每一个属性添加一个BoundFieldEmployeeIDLastNameFirstNameTitleHireDateReportsTo以及Country。在这个报表中,我们不希望看到EmployeeIDReportsTo以及Country属性。要删除这些BoundField的话,你可以:

 

·         使用字段对话框 - 在GridView的智能标签的弹出菜单中点击“编辑列”(Edit Columns)。然后,在左下角的列表中选中你想要删除的BoundField并点击那个带红叉的按钮,就可以删除这个BoundField了。

·         手工编辑GridView的声明语句 - 在源视图(Source view)中,找到你想要删除的BoundField,就是那些<asp:BoundField>元素,删了就行了。

 

在你删了EmployeeID、ReportsTo和Country等BoundField之后,你的GridView的标记语言代码应该像这个样子:

 

 

  None.gif < asp:GridView  ID ="GridView1"  runat ="server"  AutoGenerateColumns ="False"  DataKeyNames ="EmployeeID"
  None.gif    DataSourceID ="ObjectDataSource1" >
  None.gif     < Columns >
  None.gif         < asp:BoundField  DataField ="LastName"  HeaderText ="LastName"  SortExpression ="LastName"  />
  None.gif         < asp:BoundField  DataField ="FirstName"  HeaderText ="FirstName"  SortExpression ="FirstName"  />
  None.gif         < asp:BoundField  DataField ="Title"  HeaderText ="Title"  SortExpression ="Title"  />
  None.gif         < asp:BoundField  DataField ="HireDate"  HeaderText ="HireDate"  SortExpression ="HireDate"  />
  None.gif     </ Columns >
  None.gif </ asp:GridView >
None.gif

 

让我们花点时间在浏览器中来看看我们的成果。这时,你将看到一个表格,表格中每一个记录都是一个雇员的信息,一共有四列:一个是雇员的姓,一个是名字,一个是头衔,还有一个是他们的受雇日期。

aspnet_tutorial12_TemplateFieldsInGV_cs_figure03.gif

图三:每一个雇员信息都显示了LastNameFirstNameTitleHireDate


第二步:将姓和名显示在一列中

现在,每一个雇员的姓和名都是分开在两列中显示的。把它们放到一个列中显示出来也许是一个不错的主意。要做到这一点,我们需要用到TemplateField。我们可以添加一个新的TemplateField,给它加上一些必须的标记语言和数据绑定代码,然后删除原来的FirstName LastName这两个BoundField;当然,我们也可以将FirstName这个BoundField直接转换成一个TemplateField,编辑它以加上LastName的值,然后再删除LastName这个BoundField

 

两种办法都行,不过我个人还是比较喜欢直接转换的那种,因为这种方式可以自动的添加一个含有Web控件和相应的数据绑定代码的ItemTemplateEditItemTemplate,它们可以用来模仿一个BoundField的呈现和功能。这样做的好处自然是不言而喻的,因为转换的过程已经帮我们做了很多事情,那我们当然就可以节约不少的时间了。

 

要将一个BoundField转换成TemplateField,我们可以在GridView的智能标签的弹出菜单中点击“编辑列”(Edit Columns)。在弹出对话框的左下角的列表中选择需要转换的BoundField,然后点击右下角的“将此列转换成模板列”(Convert this field into a TemplateField)即可。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure04.gif

图四:在字段对话框中,将一个绑定列转换成一个模板列

 

让我们继续将FirstName这个BoundField转换成TemplateField。在这个更改之后,设计器中并没有什么明显的不同。这是因为将BoundField转换成TemplateField时,其实是创建了一个维持之前的BoundField的外观和感觉的TemplateField。尽管在设计器中没有视觉上的变化,但是这个转换的过程已经将BoundField的声明代码——<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />——改成了如下所示的TemplateField的声明代码:

 <asp:TemplateField HeaderText="FirstName" SortExpression="FirstName">
None.gif    <EditItemTemplate>
None.gif        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("FirstName") %>'></asp:TextBox>
None.gif    </EditItemTemplate>
None.gif    <ItemTemplate>
None.gif        <asp:Label ID="Label1" runat="server" Text='<%# Bind("FirstName") %>'></asp:Label>
None.gif    </ItemTemplate>
None.gif</asp:TemplateField>
None.gif

 

就像你看到的那样,TemplateField由两个模板组成——一个ItemTemplate,它有一个Label控件,其Text属性被设置为FirstName数据字段的值;还有一个EditItemTemplate,它有一个TextBix控件,其Text属性也被设置为FirstName数据字段的值。数据绑定语法——

<%# Bind("fieldName") %>——说明数据字段fieldName 被绑定到了这个特定的Web控件的属性上。

 

要将LastName添加到TemplateField中,我们需要为ItemTemplate添加一个Label控件并将其Text属性绑定到LastName上。通过设计器或是手工编写代码都可以做到这一点。要手工写代码的话,只需简单的将相应的声明代码添加到ItemTemplate中即可,如下所示:

 

  None.gif < asp:TemplateField  HeaderText ="FirstName"  SortExpression ="FirstName" >
  None.gif     < EditItemTemplate >
  None.gif         < asp:TextBox  ID ="TextBox1"  runat ="server"  Text ='<%#  Bind("FirstName") % > '> </ asp:TextBox >
  None.gif     </ EditItemTemplate >
  None.gif     < ItemTemplate >
  None.gif         < asp:Label  ID ="Label1"  runat ="server"  Text ='<%#  Bind("FirstName") % > '> </ asp:Label >
  None.gif         < asp:Label  ID ="Label2"  runat ="server"  Text ='<%#  Bind("LastName") % > '> </ asp:Label >
  None.gif     </ ItemTemplate >
  None.gif </ asp:TemplateField >
None.gif

 

要通过设计器来添加的话,还是在GridView的智能标签的弹出菜单中点击“编辑列”( Edit Templates)。这样会显示GridView的模板编辑界面。在这个界面中,智能标签是GridView中模板的列表。因为这个时候我们只有一个TemplateField,所以下拉列表中只有FirstName的各种模板和EmptyDataTemplate以及PagerTemplate。如果指定了EmptyDataTemplate模板的话,它将用于绑定到GridView的数据源中没有任何记录时的输出呈现;如果指定了PagerTemplate,它将用于呈现GridView的分页界面。

aspnet_tutorial12_TemplateFieldsInGV_cs_figure05.gif

图五:GridView的模板列可以通过设计器来编辑

 

要在FirstName模板列中同时显示LastName,从工具箱中拖一个Label到FirstName模板列的ItemTemplate中即可,当然,这要在GridView的模板编辑界面中才行的,如下图所示:

aspnet_tutorial12_TemplateFieldsInGV_cs_figure06.gif

图六:向FirstName模板列的ItemTemplate中添加一个Label

 

现在,添加到TemplateField的Label控件的Text属性还是“Label”。我们需要修改这个以使这个属性绑定到数据源中的LastName字段上。我们可以通过在Label控件的智能标记上点击一下,然后在弹出菜单中选择“编辑数据绑定”( Edit DataBindings)选项,如下图所示:

aspnet_tutorial12_TemplateFieldsInGV_cs_figure07.gif

图七:从Label的智能标签上选择Edit DataBindings选项

在弹出的数据绑定对话框中,你可以在左边的列表中选择需要绑定的属性,然后在右边的下来框中选择一个数据字段。好了,我们现在在左边选择Text属性,然后在右边选择LastName字段,点击OK

aspnet_tutorial12_TemplateFieldsInGV_cs_figure08.gif

图八:将Text属性绑定到LastName字段上

 

注意:数据绑定对话框允许你声明一个双向的数据绑定。如果你保持“双向数据绑定” (Two-way databinding)这个复选框为未选中的话,数据绑定的代码将会是<%# Eval("LastName")%>而不是<%# Bind("LastName")%>。不过,对于本节教程来说,两个种做法的效果都是OK的。双向数据绑定在插入和编辑数据的时候将会比较重要。但是如果仅仅是简单的显示数据的话,两种做法都是一样的。我们将在今后的章节中详细的讨论一下双向数据绑定。

 

让我们再花一些时间到浏览器中看看这个页面。就像你看到的那样,GridView仍然包含4列,不过,FirstName列里面显示了姓和名两个数据。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure09.gif

图九:姓和名显示在同一列里面了

 

要完成这一步,我们先删除LastName这个绑定列,并将FirstName这个模板列的列头文本(HeaderText)改成“Name”。在这之后,GridView的声明代码将会像下面这样:

 

 

  None.gif < asp:GridView  ID ="GridView1"  runat ="server"  AutoGenerateColumns ="False"  DataKeyNames ="EmployeeID"
  None.gif    DataSourceID ="ObjectDataSource1" >
  None.gif     < Columns >
  None.gif         < asp:TemplateField  HeaderText ="Name"  SortExpression ="FirstName" >
  None.gif             < EditItemTemplate >
  None.gif                 < asp:TextBox  ID ="TextBox1"  runat ="server"  Text ='<%#  Bind("FirstName") % > '> </ asp:TextBox >
  None.gif             </ EditItemTemplate >
  None.gif             < ItemTemplate >
  None.gif                 < asp:Label  ID ="Label1"  runat ="server"  Text ='<%#  Bind("FirstName") % > '> </ asp:Label >
None.gif                 < asp:Label  ID ="Label2"  runat ="server"  Text ='<%#  Eval("LastName") % > '> </ asp:Label >
None.gif             </ ItemTemplate >
None.gif         </ asp:TemplateField >
None.gif         < asp:BoundField  DataField ="Title"  HeaderText ="Title"  SortExpression ="Title"  />
None.gif         < asp:BoundField  DataField ="HireDate"  HeaderText ="HireDate"  SortExpression ="HireDate"  />
None.gif     </ Columns >
None.gif </ asp:GridView >
None.gif

aspnet_tutorial12_TemplateFieldsInGV_cs_figure10.gif

图十:每一个雇员的姓和名都显示在同一列里面了


第三步:使用Calendar控件显示HiredDate字段

在GridView中将数据显示为文本的话,只需要简单的使用BoundField就可以了。然而,在某些特定的场合,数据最好是展示为一个特殊的Web控件而不是一个简单的文本。这样的自定义的数据显示就可以用TemplateField来做。比如说,比起将雇员的雇佣日期显示成文本来说,我们觉得将其高亮的显示在一个Calendar(使用Calendar控件)中会更爽一些。

 

要做到这一点,先将HiredDate这个绑定列转换成一个模板列。像之前做的那样转换就是了,大家应该还没有忘记吧?在GridView的智能标签那里下手就可以了。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure11.gif

图十一:将HiredDate绑定列转换成一个模板列

 

就像我们在第二步中看到的那样,这个操作会将绑定列替换成一个含有ItemTemplate和EditItemTemplate的模板列,其中的ItemTemplate和EditItemTemplate分别带有一个Label和一个TextBox,而这个Label和TextBox的Text属性都使用了数据绑定语句<%# Bind("HiredDate")%>来将HireDate绑定到自己身上。

 

要用Calendar控件来替换这个文本的话,我们可以编辑模板:删除Label控件,并添加上一个Calendar控件。在设计器中,从GridView的智能标签的弹出菜单中选择“编辑模板”(Edit Templates),并在下拉列表中选择HireDate模板列的ItemTemplate。然后,删除Label控件并从工具箱中拖一个Calendar控件到模板编辑界面中。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure12.gif

图十二:给HireDate模板列的ItemTemplate添加一个Calendar控件

 

这个时候,GridView中每一行的HireDate模板列都会包含一个Calendar控件。不过,雇员的实际雇佣日期还没有设置到Calendar控件上,这就让Calendar控件默认的显示为当前的日期。我们可以通过将雇员的HireDate赋值给Calendar控件的SelectedDateVisibleDate属性来修正这个问题。

 

从Calendar控件的智能标签中选择“编辑数据绑定”。然后,把SelectedDate和VisibleDate这两个属性都绑定到HireDate字段上。

aspnet_tutorial12_TemplateFieldsInGV_cs_figure13.gif

图十三:将SelectedDate和VisibleDate都绑定到HireDate字段上

 

注意:Calendar控件的选定日期不一定要可见。举个例子来说,某个Calendar控件的选定日期为1999年4月1日,但却显示的是现在的年月。选定日期和可见日期是由Calendar控件的SelectedDate和VisibleDate属性来指定的。因为我们不仅希望选中雇员的HireDate,还希望它是可见的,那么我们就需要将这两个属性都绑定到HireDate字段上。

 

现在,我们再到浏览器中看看这个页面,Calendar现在显示的是雇员的雇员受雇日期的月份并选中了一个指定的日期。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure14.gif

图十四:雇员的受雇日期显示到了Calendar控件上

 

注意: 和我们一直所见到的那些例子相反,在本节教程中我们并没有将GridView的EnableViewState属性设置为false。这样做的原因是,在Calendar控件上的点击将会产生一个回发(PostBack),并将Calendar的选定日期设置为刚才所点击的那个日期。如果禁用了GridView的ViewState,那么每一次回发都将导致GridView使用原来的数据重新绑定,这样Calendar的选定日期就会变成原来的雇员受雇日期。

 

在本教程中,这是一个没有意义的议题,因为用户本来就不应该可以修改雇员的受雇日期。可能直接配置Calendar控件为不可选是最好的办法。不过不管怎么说,在本教程中可以看到,某些情况下还是将控件的ViewState启用才能提供某些特定的功能的。

 

第四步:显示雇员在公司工作了多少天

到现在,我们已经看到了TemplateField的两个应用:

 

·         将两个数据合并到一个列中

·         用一个Web控件来展示数据,而不是用一个简单的文本


第三种TemplateField的用法是,显示GridView中数据的元数据。比如说,除了显示雇员的受雇日期,我们可能还希望用一列来显示这个雇员在公司干了多久。

 

另外还有一种用法,它将在某些情况下需要用到,比如说在页面上某个数据的显示格式需要用一种不同于其在数据库中的存储格式的时候。想象一下,雇员表中有一个性别字段,其中存储了M或是F这样的字符用于表示此雇员是男的还是女的。当我们需要将这个信息显示在页面上的时候,我们可能希望能够将其显示为“男”或“女”而不是“M”或“F”。

 

这两种用法都可以采用在ASP.NET页面的后置代码类(或者是在一个独立的类库中,将其实现为一个静态方法)创建一个供模板调用的格式化方法(formatting method)来做到。这样的格式化方法将在模板中调用,语法跟前面的数据绑定语法是一样的。格式化方法可以接受若干个参数,但是必须返回一个字符串。这个返回的字符串是一个用于插入到模板中的HTML。

 

让我们增加一点内容来说明这个概念。主要是增加一列以显示雇员在公司干活的天数。这个格式化方法接受一个Northwind.EmployeesRow对象,然后返回以字符串的形式返回这个雇员在公司干活的天数。这个方法可以添加到ASP.NET页面的后置代码类中,不过一定要记得将其标记为protected或public,不然模板就访问不到它了。

 

 

  None.gif protected  string  DisplayDaysOnJob(Northwind.EmployeesRow employee)
  ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 InBlock.gif    // 确保HiredDate不为空……如果为空的话,返回“Unknown”
 InBlock.gif    if (employee.IsHireDateNull())
 InBlock.gif        return "Unknown";
 InBlock.gif    else
 ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 InBlock.gif        // 返回当前日期/时间与HireDate之间所隔的天数 
 InBlock.gif        TimeSpan ts = DateTime.Now.Subtract(employee.HireDate);
 InBlock.gif        return ts.Days.ToString("#,##0");
 ExpandedSubBlockEnd.gif    }

 ExpandedBlockEnd.gif}

None.gif


由于HiredDate可能会含有空值,所以我们必须在进行计算之前首先保证其值不为空。如果HiredDate值为空的话,直接返回一个“Unknown”就是了;如果不为空的话呢,就计算当前时间跟HiredDate的值之间所隔的天数,并把它作为一个字符串返回即可。

 

要使用这个方法,我们需要在GridView的TemplateField中使用数据绑定语法来调用它。同样,我们还是先给GridView添加一个新的模板列。


 aspnet_tutorial12_TemplateFieldsInGV_cs_figure15.gif

图十五:给GridView添加一个新的模板列

 

将这个新的模板列的页眉文本(HeaderText)设置成“Days on the Job”,并将其ItemStyle的水平对齐(HorizontalAlign)设置为居中(Center)。要调用DisplayDaysOnJob方法,我们需要给这个模板列添加一个ItemTemplate并加上如下的数据绑定代码:

 

 

ExpandedBlockStart.gif ContractedBlock.gif <% dot.gif # DisplayDaysOnJob((Northwind.EmployeesRow) ((System.Data.DataRowView) Container.DataItem).Row)  %>


Container.DataItem返回数据源对象中的一个相应的DataRowView对象给GridView。它的Row属性返回一个强类型化的Nothwind.EmployeesRow,然后再将其传递给DisplayDaysOnJob方法。这个数据绑定语法可以直接出现再ItemTemplate(就像下面的代码中那样)中或是赋值给Label控件的Text属性。

 

注意:除了传递一个EmployeesRow的实例,其实我们也可以仅仅传递HireDate的值,使用<%# DisplayDaysOnJob(Eval("HireDate")) %>就可以了。不过呢,Eval方法将返回一个object类型,所以我们就必须要修改DisplayDaysOnJob方法的签名以使其可以接受一个object类型的参数。我们不能将Eval("HireDate")调用的结果隐式的转换成一个DateTime类型,因为Employees表的HireDate字段是允许为空的。因此,我们需要使DisplayDaysOnJob方法可以接受一个object类型的参数,并判断这个参数是不是空值(我们可以使用Convert.IsDBNull(objectToCheck)来完成这个验证工作),然后再进行后面的操作。

 

就是因为这个,所以我还是选择了传递整个EmployeesRow实例。在下一节教程中,我们会看到一个更加合适使用Eval("columnName")来传递参数给格式化方法的例子。

 

在给我们的GridView添加了模板列并在ItemTemplate中添加了调用DisplayDaysOnJob方法的代码后,声明代码应该是这个样子:

 

 

  None.gif < asp:GridView  ID ="GridView1"  runat ="server"  AutoGenerateColumns ="False"  DataKeyNames ="EmployeeID"
  None.gif    DataSourceID ="ObjectDataSource1" >
  None.gif     < Columns >
  None.gif         < asp:TemplateField  HeaderText ="Name"  SortExpression ="FirstName" >
  None.gif             < EditItemTemplate >
  None.gif                 < asp:TextBox  ID ="TextBox1"  runat ="server"  Text ='<%#  Bind("FirstName") % > '> </ asp:TextBox >
  None.gif             </ EditItemTemplate >
  None.gif             < ItemTemplate >
  None.gif                 < asp:Label  ID ="Label1"  runat ="server"  Text ='<%#  Bind("FirstName") % > '> </ asp:Label >
None.gif                 < asp:Label  ID ="Label2"  runat ="server"  Text ='<%#  Eval("LastName") % > '> </ asp:Label >
None.gif             </ ItemTemplate >
None.gif         </ asp:TemplateField >
None.gif         < asp:BoundField  DataField ="Title"  HeaderText ="Title"  SortExpression ="Title"  />
None.gif         < asp:TemplateField  HeaderText ="HireDate"  SortExpression ="HireDate" >
None.gif             < EditItemTemplate >
None.gif                 < asp:TextBox  ID ="TextBox2"  runat ="server"  Text ='<%#  Bind("HireDate") % > '> </ asp:TextBox >
None.gif             </ EditItemTemplate >
None.gif             < ItemTemplate >
None.gif                 < asp:Calendar  ID ="Calendar1"  runat ="server"  SelectedDate ='<%#  Bind("HireDate") % > '
ExpandedBlockStart.gifContractedBlock.gif                    VisibleDate=' <% dot.gif # Eval("HireDate")  %> '> </ asp:Calendar >
             </ ItemTemplate >
None.gif         </ asp:TemplateField >
None.gif         < asp:TemplateField  HeaderText ="Days On The Job" >
None.gif             < ItemTemplate >
ExpandedBlockStart.gifContractedBlock.gif                 <% dot.gif # DisplayDaysOnJob((Northwind.EmployeesRow) ((System.Data.DataRowView) Container.DataItem).Row)  %>
None.gif             </ ItemTemplate >
None.gif             < ItemStyle  HorizontalAlign ="Center"  />
None.gif         </ asp:TemplateField >
None.gif     </ Columns >
None.gif </ asp:GridView >
None.gif


完成了整节教程之后,页面在浏览器中的样子应该是图十六的这个样子。


aspnet_tutorial12_TemplateFieldsInGV_cs_figure16.gif

图十六:“雇员在公司干了多久“也显示出来了

 

总结 

 

在GridView控件中,相对于其他的列控件来说,模板列可以处理更加复杂的数据呈现。模板列主要用于这样一些情况:

 

·         一个GridView列中需要显示多个数据列

·         使用一个Web控件来展示数据比一段简单的文本更好

·         页面的输出取决于绑定到GridView的数据,比如说元数据或者说是数据的重新格式化

 

除了自定义数据的显示,模板列也用于编辑和插入数据时的用户界面的自定义,这个我们在后面的章节中将会讲到。

 

接下来的两节中,我们会继续讨论模板,我们会先看看在DetailsView中使用模板列的情况。跟着我们再去看看FormView,这玩意儿就是用模板来实现一个更加复杂的呈现,当然,用的是一大堆的字段。

编程愉快!

转载于:https://www.cnblogs.com/matter/archive/2006/09/24/513578.html

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
<p> <span style="color:#337FE5;"><strong>【为什么还需要学习C++?】</strong></span> </p> <p style="margin-left:0cm;"> 你是否接触很多语言,但从来没有了解过编程语言的本质? </p> <p style="margin-left:0cm;text-align:start;"> 你是否想成为一名资深开发人员,想开发别人做不了的高性能程序? </p> <p style="margin-left:0cm;text-align:start;"> 你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? </p> <p style="margin-left:0cm;text-align:start;">   </p> <p style="margin-left:0cm;text-align:start;"> 那么C++就是你个人能力提升,职业之路进阶的不二之选。 </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p style="margin-left:0cm;"> <strong><span style="color:#337FE5;">【课程特色】</span></strong> </p> <p style="margin-left:0cm;text-align:start;"> 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。 </p> <p style="margin-left:0cm;text-align:start;"> 2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。 </p> <p style="margin-left:0cm;text-align:start;"> 3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。 </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p class="ql-long-24357476"> <span style="color:#337FE5;"><strong>【学完后我将达到什么水平?】</strong></span> </p> <p class="ql-long-24357476"> 1.对C++的各个知识能够熟练配置、开发、部署; </p> <p class="ql-long-24357476"> 2.吊打一切关于C++的笔试面试题; </p> <p class="ql-long-24357476"> 3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。 </p> <p class="MsoNoSpacing" style="margin-left:18pt;"> <br /> </p> <div> <br /> </div> <p> <br /> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#337FE5;"><strong>【面向人群】</strong></span> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#222226;font-family:PingFangSC-Regular, "font-size:14px;background-color:#FFFFFF;">1.希望一站式快速入门的C++初学者;</span> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#222226;font-family:PingFangSC-Regular, "font-size:14px;background-color:#FFFFFF;">2.希望快速学习 C++、掌握编程要义、修炼内功的开发者;</span> </p> <p style="margin-left:0cm;text-align:start;"> <span style="color:#222226;font-family:PingFangSC-Regular, "font-size:14px;background-color:#FFFFFF;">3.有志于挑战更高级的开发项目,成为资深开发的工程师。</span> </p> <p style="margin-left:0cm;text-align:start;"> <br /> </p> <p> <br /> </p> <p> <span style="color:#337FE5;"><strong>【课程设计】</strong></span> </p> <p> 本课程包含3大模块 </p> <p> <strong>基础篇</strong><br /> 本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。 </p> <p> <br /> <strong>进阶篇</strong><br /> 本篇主要讲解编程常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。 </p> <p> <br /> <strong>提升篇:</strong><br /> 本篇可以帮助学员更加高效的进行c++开发,其包含类型转换、文件操作、异常处理、代码重用等内容。 </p> <p> <img src="https://img-bss.csdnimg.cn/202007091130239667.png" alt="" /> </p>
百度云盘分享 简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级、级、高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情、执着,对IT的憧憬、向往!此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存清除,从账户取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始化一个EJB实例 5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口函数得到远程接口的引用,用远程接口的引用访问EJB。 EJBJNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户可以在终端上直接地使用它,但是它的主要作用是供程序使用的。本规范尝试满足大型主机、微型主机、个人工作站、和TACs 的不同需求。例如,容易实现协议的设计。 Java EJB有、无状态SessionBean的两个例子 两个例子,无状态SessionBean可会话Bean必须实现SessionBean,获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,计算利息等;在有状态SessionBean,用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存清除…… Java Socket 聊天通信演示代码 2个目标文件,一个服务器,一个客户端。 Java Telnet客户端实例源码 一个目标文件,演示Socket的使用。 Java 组播组发送和接受数据实例 3个目标文件。 Java读写文本文件的示例代码 1个目标文件。 java俄罗斯方块 一个目标文件。 Java非对称加密源码实例 1个目标文件 摘要:Java源码,算法相关,非对称加密   Java非对称加密源程序代码实例,本例使用RSA加密技术,定义加密算法可用 DES,DESede,Blowfish等。   设定字符串为“张三,你好,我是李四”   产生张三的密钥对(keyPairZhang)   张三生成公钥(publicKeyZhang)并发送给李四,这里发送的是公钥的数组字节   通过网络或磁盘等方式,把公钥编码传送给李四,李四接收到张三编码后的公钥,将其解码,李四用张三的公钥加密信息,并发送给李四,张三用自己的私钥解密从李四处收到的信息…… Java利用DES私钥对称加密代码实例 同上 java聊天室 2个目标文件,简单。 java模拟掷骰子2个 1个目标文件,输出演示。 java凭图游戏 一个目标文件,简单。 java求一个整数的因子 如题。 Java生成密钥的实例 1个目标文件 摘要:Java源码,算法相关,密钥   Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥,通常应对私钥加密后再保存、如何从文件得到公钥编码的字节数组、如何从字节数组解码公钥。 Java数据压缩与传输实例 1个目标文件 摘要:Java源码,文件操作,数据压缩,文件传输   Jav
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页