hysql.org技术站
当前位置:首页 > ASP.NET > 正文

在ASP.NET 2.0中操作数据之十一:基于数据的自定义

07-13 ASP.NET

介绍

  我们可以通过控制HeaderStyle, RowStyle, AlternatingRowStyle和其他一些属性来改变GridView, DetailsView, 和 FormView的样式,比如cssClass, Font, BorderWidth, BorderStyle, Bar, Width, Height等

  一般,自定义格式化与我们所要显示的数据的值有关系。例如, 为了吸引用户注意那些库存为空的产品,我们可以将库存对应的字段UnitsInStock  和UnitsOnOrder为0的数据背景色设为黄色. 为了高亮化那些贵的产品,则将UnitsInStock  高于$75.00的数据字体设置为粗体

  GridView, DetailsView, FormView的格式自定义可以有多种方法, 在本文中我们将用DataBound 和 RowDataBound两种事件来完成, 在下一篇里我们将尝试用alternative的方式 在GridView控件中使用TemplateField

  使用DetailsView 控件的 DataBound 事件当绑定数据到DetailsView控件, 不管是从数据控件或编码填充数据到DataSource属性并调用其DataBind()方法。以下几种事件将触发

1.DataBinding事件触发

2.数据绑定到数据绑定控件

3.DataBound事件触发

  一般在1,2,3之后数据将会通过事件立即填充数据控件,我们还可以自定义事件处理来确定数据是否已经被填充到控件中并按照我们的需要调整显示格式。我们可以来做个例子.我们将创建一个DetailsView来列出一个产品的一般信息,并且当UnitPrice超过 $75.00 时用粗体,italic字体来显示UnitPrice的值

Step 1: 在DetailsView中显示产品信息

  在CustomFormatting文件夹下新建一个CustomColors.aspx页面,从工具箱中拖出一个DetailsView控件到页面中,设置ID为ExpensiveProductsPriceInBoldItalic绑定到一个新的数据源中,并配置此数据源到业务对象ProductsBLL类中的GetProducts()方法,这个的详细实现步骤已经在前面详细介绍过了,这里就忽略了

  当您绑定ObjectDataSource到DetailsView时,我们可以修改一下字段列表,我选择移除了ProductID, SupplierID, CategoryID, UnitsInStock, UnitsOnOrder, ReorderLevel和那些不被绑定的字段,他们将不会显示在DetailsView列表中,而那些留下来的我们可以重命名他们,还可以修改他们的显示格式. 我还清空了DetailsView的Height和Width属性,这样当显示的只有一条数据时不会出现样式的混乱。当然我们面对的数据绝不只有一条这么少,显示怎么办呢?我们可以检查DetailsView的智能感知中检查Enable Paging checkbox是否被勾选上, 这样我们可以分页查看所有的数据了

http://files.jb51.net/file_images/article/201605/2016050609292413.png

图1: 在DetailsView的值能感知中检查Enable Paging属性是否被勾选上

 在经过这些改变后, DetailsView的代码更改为

<asp:DetailsView ID="DetailsView1" runat="server" AllowPaging="True" AutoGenerateRows="False" DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">

 <Fields>

 <asp:BoundField DataField="ProductName" HeaderText="Product" SortExpression="ProductName"

/>

 <asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"

SortExpression="CategoryName" />

 <asp:BoundField DataField="SupplierName" HeaderText="Supplier" ReadOnly="True"

SortExpression="SupplierName" />

 <asp:BoundField DataField="QuantityPerUnit" HeaderText="Qty/Unit"

SortExpression="QuantityPerUnit" />

 <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price"

  HtmlEncode="False" SortExpression="UnitPrice" />

 </Fields>

</asp:DetailsView>

您这时可以按F5执行看看

http://files.jb51.net/file_images/article/201605/2016050609292414.png

图2: DetailsView控件一次显示一个数据

Step 2: 在DataBound事件中编码确定数据的值

  为了将那些UnitPrice高于$75.00的产品用粗体,italic字体显示出来,我们首先需要编码确定UnitPrice的值,对于DetailsView我们可以通过DataBound事件完成. 我们选择DetailsView并查看属性视图(F4位快捷键), 如果没有显示,则选择 View(视图)Property Window(属性窗口), 在确保您选择了DetailsView的情况下双击DataBound事件或者输入您要创建的事件名

http://files.jb51.net/file_images/article/201605/2016050609292815.png

图3: 为DataBound事件创建一个事件处理

代码中将会自动生成以下代码

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)
{

}

  我们可以通过DataItem属性来设置DetailsView的绑定项(一些强类型的数据行(DataRow)组成的强类型的数据表(DataTable)), 当数据表(DataTable)绑定到DetailsView时,数据表的第一行将被自动绑定到DetailsView的DataItem属性,而DataItem属性中包含有DataRowView (Object类型),我们可以通过DataRowView来访问一个ProductsRow 的DataRow实例,还可以检测Object的值来确定ProductsRow实例是否存在

下面的代码描述如何确定UnitPrice是否绑定到DetailsView并且高于$75.00

protected void ExpensiveProductsPriceInBoldItalic_DataBound(object sender, EventArgs e)

{

 // Get the ProductsRow object from the DataItem property...

 Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)

ExpensiveProductsPriceInBoldItalic.DataItem).Row;

 if (!product.IsUnitPriceNull() && product.UnitPrice > 75m)

 {

 // TODO: Make the UnitPrice text bold and italic

 }

}

注意: 当UnitPrice在数据库的值为空,我们在绑定到ProductsRow's UnitPrice属性之前检查确定他是否为空,这很重要因为我们可以通过检查这个属性来抛出一个强类型的异常 StrongTypingException exception.

Step 3: 在DetailsView中格式化 UnitPrice

  到这个时候我们已经知道即将绑定的UnitPrice是否高于$75.00,现在我们来看看怎么通过编码调整UnitPrice的格式,我们可以通过修改DetailsViewID.Rows[index];修改一行数据,而且我们可以通过访问DetailsViewID.Rows[index].Cells[index]来访问某一单元格,这样我们可以通过修改与格式相关的属性来格式化这一单元格

  访问某一行需要得到某行的索引,索引从0开始, UnitPrice 在 DetailsView中是第15行, 假设他在第四行那么我们可以通过ExpensiveProductsPriceInBoldItalic.Rows[4]来访问. 这时我们可以通过下面的代码将这一行显示为粗体,italic 字体

ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Bold = true;

ExpensiveProductsPriceInBoldItalic.Rows[4].Font.Italic = true;

然而,这样将会格式化Label和值,如果我们只想将值格式话,而且我们需要将格式应用到当前行的第二格,请看下面的代码

ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Bold = true;

ExpensiveProductsPriceInBoldItalic.Rows[4].Cells[1].Font.Italic = true;

  

我们还可以通过StyleSheet 来显示标记和样式相关信息,而不是用确定的某一行某一列来设置格式,我们用CSS来控制格式,打开Styles.css 文件,添加一个新的Class命名为ExpensivePriceEmphasis按照下面的代码CSS

.ExpensivePriceEmphasis

{

 font-weight: bold;

 font-style: italic;

}

然后再DataBound事件中,设置单元的CssClass为ExpensivePriceEmphasis,在DataBound事件处理中添加

当查看Chai(费用低于$75.00),价格将会用正常格式显示 图4),但是当查看Mishi Kobe Niku,(价格为$97.00)则会用我们设置的格式显示(图5)

http://files.jb51.net/file_images/article/201605/2016050609292816.png

图4: 价格低于$75.00将会用正常格式显示

http://files.jb51.net/file_images/article/201605/2016050609292817.png

图5: 价格高于$75.00将会用 粗体, Italic 字体显示

  使用FormView控件的 DataBound 事件绑定到FormView数据的步骤和DetailsView的步骤类似都要创建一个DataBound事件处理, 声明绑定到控件的DataItem类型属性, 然后执行绑定。然而,他们更新的方式不同

  FormView不包括任何绑定列也不包含行的集合, 取而代之的是他由一系列包含若干静态HTML, Web控件,绑定表达式的模板组合。调整 FormView的外观涉及到调整一个或多个FormView的模板

  让我们像前一个例子那样用FormView列出产品项,但是这次我们仅仅用红色字体显示units小于等于10的产品的name和units

Step 1: 在FormView中显示产品信息

  添加一个FormView到CustomColors.aspx中,设置其ID为LowStockedProductsInRed,像前一个步骤一样绑定数据到ObjectDataSource中, 这将在FormView中创建ItemTemplate, EditItemTemplate, 和InsertItemTemplate .

  移除EditItemTemplate和InsertItemTemplate 并在 ItemTemplate 中仅包含ProductName 和UnitsInStock 项, 在智能感知中检查Allow Paging(分页)标记是否被选上

在这些操作后FormView的代码大概会成这样

<asp:FormView ID="LowStockedProductsInRed" runat="server" DataKeyNames="ProductID"

 DataSourceID="ObjectDataSource1" AllowPaging="True" EnableViewState="False">  

 <ItemTemplate>

 <b>Product:</b>

 <asp:Label ID="ProductNameLabel" runat="server" Text='<%# Bind("ProductName") %>'>

 </asp:Label><br />

 <b>Units In Stock:</b>

 <asp:Label ID="UnitsInStockLabel" runat="server" Text='<%# Bind("UnitsInStock") %>'>

 </asp:Label>

 </ItemTemplate>

</asp:FormView>

 注意ItemTemplate 包含的代码:

·静态HTML – “Product:” 和 “Units In Stock:” 包含 <br /> 和 <b> 元素.

·Web 控件– 两个Label控件, ProductNameLabel 和UnitsInStockLabel.

·绑定表达式 –<%# Bind("ProductName") %> 和<%# Bind("UnitsInStock") %> 表达式, 绑定值到Label的Text属性上

Step 2: 在 DataBound 事件处理中编码确定数据的值

当FormView的标记完成后,下一步就是确定UnitsInStock的值是否小于等于10,这里和在DetailView中类似,先创建DataBound事件

http://files.jb51.net/file_images/article/201605/2016050609292818.png

图6: 创建 DataBound 事件处理

在事件中声明FormView的DataItem属性到ProductsRow实例中,确定UnitsInPrice的值并将对应的值用红色字体显示

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)

{

 // Get the ProductsRow object from the DataItem property...

 Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)

LowStockedProductsInRed.DataItem).Row;

 if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)

 {

 // TODO: Make the UnitsInStockLabel's text red

 }

}

Step 3:在FormView 的ItemTemplate中格式化UnitsInStockLabel Label

最后一步就是要在ItemTemplate中设置UnitsInStockLabel的样式为红色字体,在ItemTempelete中查找控件可以使用FindControl(“controlID”)方法

WebControlType someName = (WebControlType)FormViewID.FindControl("controlID");

对于我们这个例子我们可以用如下代码来查找该Label控件

Label unitsInStock = (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");

当我们找到这个控件时则可以修改其对应的style属性,在style.css中已经有一个写好的LowUnitsInStockEmphasis的cSS Class ,我们通过下面的代码将cSS Class设置到对应的属性

protected void LowStockedProductsInRed_DataBound(object sender, EventArgs e)

{

 // Get the ProductsRow object from the DataItem property...

 Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)

LowStockedProductsInRed.DataItem).Row;

 if (!product.IsUnitsInStockNull() && product.UnitsInStock <= 10)

 {

 Label unitsInStock = (Label)LowStockedProductsInRed.FindControl("UnitsInStockLabel");



 if (unitsInStock != null)

 {

  unitsInStock.CssClass = "LowUnitsInStockEmphasis";

 }

 }

}

注意: 这种方式在FormView和GridView中也可以通过设置TemplateFields来达到同样的效果,我们将在下一篇中讨论TemplateFields.图7显示FormView在当UnitsInStock大于10的情况,图8则显示小于等于10的情况

http://files.jb51.net/file_images/article/201605/2016050609293219.png

图7 : 在高于10的情况下,没有值被格式化

http://files.jb51.net/file_images/article/201605/2016050609293220.png

图8:小于等于10时,值用红色字体显示

用GridView的 RowDataBound 事件自定义格式化

前面我们讨论了在FormView和DetailsView中实现数据绑定的步骤,现在让我们回顾下

DataBinding事件触发
数据绑定到数据绑定控件
DataBound事件触发
对于FormView和DetailsView有效因为只需要显示一个数据,而在GridView中,则要显示所有数据,相对于前面三个步骤,步骤二有些不同

在步骤二中,GridView 列出所有的数据,对于某一个记录将创建一个GridViewRow 实例并绑定,对于每个添加到GridView 中的 GridViewRow两个事件将会触发:

·RowCreated – 当GridViewRow被创建时触发

·RowDataBound – 当前记录绑定到GridViewRow时触发.

对于GridView,请使用下面的步骤

DataBinding事件触发
数据绑定到数据绑定控件
对于每一行数据..

a.创建GridViewRow

b.触发 RowCreated 事件

c.绑定数据到GridViewRow

d.触发RowDataBound事件

e.添加GridViewRow到Rows 集合

DataBound事件触发 

为了自定义格式化GridView单独记录,我们需要为RowDataBound事件创建事件处理,让我们添加一个GridView到CustomColors.aspx中,并显示name, category, 和 price,用黄色背景高亮那些价格小于$10.00的产品

Step 1:在GridView中显示产品信息

  添加一个GridView到FormView的下方,设置ID为HighlightCheapProducts.我们之前已经设置了一个ObjectDataSource来获取产品数据,现在我们绑定GridView到ObjectDataSource. 之后,编辑GridView的绑定列包含产品的name.categorie,price属性。完成之后GridView的代码将会是:

<asp:GridView ID="HighlightCheapProducts" runat="server" AutoGenerateColumns="False"

 DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" EnableViewState="False">

 <Columns>

 <asp:BoundField DataField="ProductName" HeaderText="Product" SortExpression="ProductName"

/>

 <asp:BoundField DataField="CategoryName" HeaderText="Category" ReadOnly="True"

SortExpression="CategoryName" />

 <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}" HeaderText="Price"

  HtmlEncode="False" SortExpression="UnitPrice" />

 </Columns>

</asp:GridView>

图九显示浏览器查看的结果

http://files.jb51.net/file_images/article/201605/2016050609293221.png

图9: GridView显示产品的name, category, price

Step 2:在RowDataBound的事件处理中编码确定数据对应的值

  当ProductsDataTable绑定到GridView,GridView将会产生若干个ProductsRow。GridViewRow的DataItem属性将会生成一个实际的ProductRow。在GridView的 RowDataBound事件发生之后,为了确定UnitsInStock的值,我们需要创建RowDataBound的事件处理,在其中我们可以确定UnitsInStock的值并做相应的格式化EventHandler的创建过程和前面两个一样

http://files.jb51.net/file_images/article/201605/2016050609293222.png

图10: 创建GridView的RowDataBound事件的事件处理

在后台代码里将会自动生成如下代码

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)

{

}

 当RowDataBound事件触发,第二个参数GridViewRowEventArgs中包含了对GridViewRow的引用,我们用如下的代码来访问GridViewRow中的ProductsRow

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)

{ // Get the ProductsRow object from the DataItem property...

 Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)

e.Row.DataItem).Row;

 if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)

 {

 // TODO: Highlight the row yellow...

 }

}

当运用RowDataBound事件处理时,GridView由各种类型不同的行组成,而事件发生针对所有的行类型, GridViewRow的类型可以由RowType属性决定,可以是以下类型中的一种

·DataRow – GridView的DataSource中的一条记录

·EmptyDataRow – GridView的DataSource显示出来的某一行为空

·Footer – 底部行; 显示由GridView的ShowFooter属性决定

·Header – 头部行; 显示由GridView的ShowHeader属性决定

·Pager – GridView的分页,这一行显示分页的标记

·Separator – 对于GridView不可用,但是对于DataList和Reapter的RowType属性却很有用,我们将在将来的文章中讨论他们

当上面四种(DataRow, Pager Rows Footer, Header)都不合适对应值时,将返回一个空的数据项, 所以我们需要在代码中检查GridViewRow的RowType属性来确定:

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)

{

 // Make sure we are working with a DataRow

 if (e.Row.RowType == DataControlRowType.DataRow)

 {

  // Get the ProductsRow object from the DataItem property...

  Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)

e.Row.DataItem).Row;

  if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)

  {

  // TODO: Highlight row yellow...

  }

 }

}

Step 3:用黄色高亮那些UnitPrice小于$10.00的行

我们需要访问GridViewID.Rows[index]来访问index对应的那一行,GridViewID.Rows[index].Cells[index]来访问某一单元格.然而当RowDataBound事件触发时,GridViewRow却没有添加到Rows集合中, 因此我们不能在RowDataBound事件处理中通过当前GridViewRow实例

取而代之,我们可以通过e.Row来访问。为了高亮某一行我们用下面的代码

e.Row.BackColor = System.Drawing.Color.Yellow;

我们还可以通过cSSClass取得同样的效果(推荐)

protected void HighlightCheapProducts_RowDataBound(object sender, GridViewRowEventArgs e)

{

 // Make sure we are working with a DataRow

 if (e.Row.RowType == DataControlRowType.DataRow)

 {

 // Get the ProductsRow object from the DataItem property...

 Northwind.ProductsRow product = (Northwind.ProductsRow)((System.Data.DataRowView)

e.Row.DataItem).Row;

 if (!product.IsUnitPriceNull() && product.UnitPrice < 10m)

 {

  e.Row.CssClass = "AffordablePriceEmphasis";

 }

 }

}

http://files.jb51.net/file_images/article/201605/2016050609294223.png

图 11: 所需要的行用高亮黄色显示

总结

  在本篇中我们演示了基于数据绑定来自定义格式化GridView, DetailsView, FormView的方法。为了完成这些,我们创建DataBound或者RowDataBound事件,为了访问DetailsView或FormView的数据绑定,我们可以通过DataItem属性。对于GridView,每个GridViewRow实例的DataItem属性包含了绑定的数据(在RowDataBound事件处理中可用)

  为了调整格式,我们可能需要访问某一特定的行,在GridView和DetailsView中我们可以通过索引访问,而在FormView中我们则需要用FindControl("controlID"),同时FindControl("controlID")通常都可以访问Web控件Tempelete中的某个控件.在下一篇中我们将讨论如何在GridView和DetailsView使用Tempeletes, 还将讨论另外一些自定义格式化的方法

祝编程快乐!

作者简介

Scott Mitchell,著有六本ASP/ASP.NET方面的书,是4GuysFromRolla.com的创始人,自1998年以来一直应用 微软Web技术。Scott是个独立的技术咨询顾问,培训师,作家,最近完成了将由Sams出版社出版的新作,24小时内精通ASP.NET 2.0。他的联系电邮为mitchell@4guysfromrolla.com,也可以通过他的博客http://scottonwriting.net/与他联系。

您可能感兴趣的文章:

  • asp.net DataFormatString格式化GridView
  • asp.net IList查询数据后格式化数据再绑定控件
  • asp.net中各种类型的JSON格式化
  • ASP.NET GridView控件在列上格式化时间及DataFormatString使用
  • Asp.net中时间格式化的6种方法详细总结
  • asp.net页面中时间格式化的示例
  • asp.net+js实现金额格式化
  • 在ASP.NET 2.0中操作数据之二十七:创建自定义排序用户界面
  • 在ASP.NET 2.0中操作数据之二十八:GridView里的Button
  • 在ASP.NET 2.0中操作数据之二十九:用DataList和Repeater来显示数据
  • 在ASP.NET 2.0中操作数据之三十:格式化DataList和Repeater的数据

相关拓展:高级格式化格式化介绍

Advanced Format又称“高级格式化”。高级格式化是国际硬盘设备与材料协会(International Disk Drive Equipment and Materials Association,IDEMA)为新型数据结构格式所采用的名称,它定义了硬盘介质上所用基本扇区大小的增长量级。高级格式化,又名4K高级格式化,要求硬盘扇区4K对齐。

硬盘行业目前正在经历扇区存储方式的变革,由盘片每扇区存储4096字节取代以往的512字节。作为最新的术语,“高级格式化”将更好地优化单碟密度,从而增加了存储空间。它应用了最新固件,从而更好地适应最新操作系统和其他配套设施的运行。长期以来,机械硬盘在储存数据时,一直都是以512byte大小的扇区(Sector)为单位分割进行读写。随着硬盘容量的不断提升,这种古老的分配标准已经越来越显的不合时宜。因此,硬盘行业决定将扇区容量扩大到4KB,该技术被称为“先进格式化”(Advanced Format)。传统的扇区分割机制中,每512byte的数据之间,需要间隔一个同步/分隔(Sync/DAM)区域和一个ECC错误校验区域。而在“先进格式化”模式下,每4KB为一个扇区,相当于把之前的8个扇区合而为一,只需要一个同步/分隔区域和一个容量稍大的ECC校验区。

西部数据公司表示,先进格式化技术更有效的利用了磁盘盘片上宝贵的存储面积,预计能够将硬盘格式化后的可用容量提升7%到11%。以西部数据64M缓存1TB容量绿盘WD10EARS为例,格式化后的实际可用容量会提升10%,这已经相当可观。相信大家也都想到了,这种变化可能会带来兼容性的问题。为避免这一问题,WD将4KB的物理扇区划分为8个依然为512Byte的逻辑扇区,新旧标准的转换工作依靠硬盘固件进行,“只要分区正确,性能就不会有损失”。

WD 高级格式化硬盘专门面向 Mac 和最新的 Windows 操作系统进行优化,如:全新安装的Windows Vista 和 Windows 7。高级格式化技术被 WD 及其它硬盘制造商所采用,以提升媒体格式化效率,从而实现更大的硬盘容量。 WD 高级格式化硬盘可能要求您在安装了操作系统或分区,并将硬盘格式化为备用硬盘之后,运行 WD Align 软件实用程序。WD Align 软件可调整高级格式化硬盘上的分区,以确保其能够为某些配置提供全性能。

版权保护: 本文由 首页 原创,转载请保留链接: http://www.hysql.org/aspnet/20180713/7697.html

友情推荐:股票配资 股票配资平台 股票配资门户 网页制作