漫漫技术人生路

C#

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  234 随笔 :: 0 文章 :: 30 评论 :: 8 引用

公告

2006年10月16日 #

ASP.NET 2.0 中增加了内建的 MasterPage 的支持,这对我们来说是一个很大的便利。然而经过一段时间的使用,我发现 MasterPage 并不是那么完美:嵌套的 MasterPage 不能支持设计时界面,以及下面要提到的Content Page 中增加 CSS 的问题。 

  通常,在没有 2.0 之前,我们在页面里要增加一个 CSS 引用的语法如下:

<link rel="stylesheet" href="css/test.css" />


  原本是很平常的做法。但是在一个 MasterPage 的子页面中,出现了一个很尴尬的局面,就是:我们该把上述代码放到什么位置?

  因为 MasterPage 的具体内容页面中,只能定义一个个的 <asp:Content /> 标签的内容。我们按照通常的做法在 aspx 里面无法对页面的 <header/> 内容进行控制。而这个 <link/> 标签又必须放在 <header/> 内。我试验过在 <asp:Content /> 内部加入这行代码,但是会提示出错的。

  同时,我们也无法在 MasterPage 的 <header/> 内部放好一个 ContentPlaceHolder 用于将来放入 CSS 的引用代码。

  因此我的做法是定义了一个 helper 类如下:

static public class ControlHelper
{
 static public void AddStyleSheet(Page page, string cssPath)
 {
  HtmlLink link = new HtmlLink();
  link.Href = cssPath;
  link.Attributes["rel"] = "stylesheet";
  link.Attributes["type"] = "text/css";
  page.Header.Controls.Add(link);
 }
}
posted @ 2006-10-16 16:41 javaca88 阅读(105) 评论(0) 编辑

repeater
<span>
<%# Eval("date","{0:dd mmm yyyy}")%>
</span>

DateTime.Now.ToString("yyyy/mm/dd")
---------------------------------------------------------------------------------------------------------------------
多层次的Master页面
如果有多个层次,就只能在Source视图中打开了<%@master>
<%@materPageFile=%>
对于多层次,就产生了中间页,就有<asp:content>标记,该标记与Master页面中的<asp:ContentPlaceHolder>标记相关联
然后在这个<asp:content>标记中有一个<asp:ContentPlaceHolder>标记,用于包含下一层的页面。
示例

本节包含三个代码示例。第一个代码示例演示如何创建嵌套母版页 .。第二个代码示例演示如何引用在第一个代码示例中创建的母版页。第三个代码示例演示如何使用内容页来引用在第二个代码示例中创建的母版页。

下面的代码示例演示如何创建嵌套母版页,并表示名为 ParentMasterPage_1 的父级母版页。

C# 复制代码<%@ Master Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html  >
<head runat="server">
    <title>Nested Master Page Example</title>
</head>
<body>
    <form id="form1" runat="server">
    <h1>This is content in the parent master page.</h1>
    <div>
        <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
        </asp:contentplaceholder>
    </div>
    </form>
</body>
</html>


下面的代码示例演示如何使用名为 ChildMasterPage_1 的嵌套母版页,它引用在前一个代码示例中创建的母版页。

C# 复制代码<%@ Master Language="C#" MasterPageFile="~/ParentMasterPage_1cs.master" %>

<asp:Content Runat="Server" ContentPlaceHolderID="ContentPlaceHolder1">
    <h2>This is the content of a nested Master Page.</h2>
    <div>
        <asp:contentplaceholder id="ContentPlaceHolder2" runat="server">
        </asp:contentplaceholder>
    </div>
</asp:Content>

下面的代码示例演示如何使用名为 ContentPage 的内容页,它引用在前一个代码示例中创建的 ChildMasterPage_1。

C# 复制代码<%@ Page Language="C#" MasterPageFile="~/ChildMasterPage_1cs.master" Title="Untitled Page"%>

<asp:content runat="server" contentplaceholderid="ContentPlaceHolder2">
This is the content of a Content control.
</asp:content>

   如同Theme可以格式化网站控件的显示模式一样,MasterPage可以定义网站中不同网页的相同部分,如格局、页头、页脚、导航栏等。可以把这些控件定义到一个MasterPage上,其它网页继承这个MasterPage即可。继承后体现在这些网页公有部分都相同,而不同部分在于MasterPage有一个ContantPlaceHolder,这个控件定义了一个可以被其它页面继承的区域,该区域可以被其它页面用来摆放自己的控件。新建Web页面时核选上使用母版,然后选择母版即可。

    注意:应用程序可以在Web.config中指定默认的母版页,如下所示:

<configuration>
    <system.web>
        <pages masterPageFile="~/Foo.master" />
    </system.web>
</configuration>

    好了.MasterPage来了,编写页面简单了,全部在ContentPage页面中填充ContentPlaceHolder就可以了...问题也就来了...现在,我某部分页面会使用一些javascript(放在一个calendar.js中),怎么办?哈,只过了0.01秒我就想到了"解决方案":往ContentPage写个连接不就完了么?类似:

<script type="text/javascript" src="../../../js/calendar.js">script>

(注意:src是ContentPage到JS文件的相对路径!!!)很好,小伙子,没有把一千多行的JS代码直接丢到页面:)但,问题是,你要把这句话丢到哪儿?费话,当然放到页面的"头上"了...呵呵.现在ContentPage都没有头了,head都在MasterPage里面去了.丢到ContentPage的ContentPlaceHolder外面?不行,HTML解晰不过去...
    谷歌了一下,学到如下知识:说白了,MasterPage就是原来页面中的控件,只不过原来都是页面包裹着控件,现在是控件包裹着页面而已:)对于客户端-Brower来说,他对MasterPage是一无所知的.当客户请求某一页面的时候,Asp.net runtime发现该页运用了MasterPage,于是把两个独立的部分按照占位符-ContentPlaceHolder将其整合起来,返回给客户,而这一过程对客户来说是透明的....
    既然这样,很简单,我们把上面那句指象js的话放到MasterPage不就完了么?(这里有一点要注意,这个时候的src,不能按照MasterPage到JS的相对路径.为什么?刚不说了么?:)OK.成功.不过"../../../"这个相对路径肯定有问题,写这个路径,完全是针对我的ContentPage,也就是说,如果其他目录的ContentPage将无法使用这个JS,这当然不行,那就把他改成绝对路径贝"~/js/..".不过理所当然的方案也不行,asp.net无法找到JS?晕了...试了好久,改了好久至今无法解决这个问题.放个针对某些页的相对路径在MasterPage当然不行.无奈之下,只能另辟捷径,最后总算发现,把上面那句JS连接的话放到每个ContentPage中的某个ContentPlaceHolder中就OK了.问题算是解决,思想算是合理,不过做法太丑陋了.....没办法,抓狂死了..

一般而言,链接路径的表达有三种方式:绝对路径、相对路径和基于根目录的路径。另外对于ASP.NET服务器控件来说,还可以使用“~”来代替根目录来表示。
在MasterPage和用户控件中,经常要使用一些图片作为背景或漂亮的按钮,但是在指定图片的src或者background时候,经常因为链接路径的问题而出错。
1.使用绝对路径:使用形如“D:\xxx\xxx.gif”的绝对文件路径一般情况下是不可取的。可以考虑采取url的方法,写成http://xxxx/xx/xxx.gif”。但是缺点是不利于移植,例如现在站点的地址为http://www.xxx.net,如果有一天站点更该http://www.xxx.com,则所有的链接地址都失效,需要进行更改,难以维护。
2.使用相对路径:使用相对于页面位置的路径,比如“..\images\xxx.gif”,这样MasterPage和用户控件中都能正确显示,但是如果将继承MasterPage的页面放到不同的文件夹下,或者使用用户控件的页面不在同一文件夹,那么该页面又会找不到正确的图片位置了!
3.基于根目录的路径:形如:<a href="/xxx/xxx.gif">这样的解决方法在ASP.NET2.0调试的时候,因为没有建立虚拟目录,并不能正确显示(我也不是很肯定,没有确认^_^)。而我在非服务器控件的HTML标签元素上无法使用“~”来指定路径。
那么,在设计时让图片可见,我们应该怎么来处理呢?我采用了CSS来完成这项工作。针对要显示图片的元素和控件,我们可以写一段简单的css来定位图片,因为css文件的位置是一般不会改变的(位于App_Theme/themename/xxx.css),这种方法也就行之有效了。
.HideBar
{
height:56px;
width:5px;
cursor:hand;
background-image: url(../../images/xxx.gif);
}接下来我们只需要在相应的元素和控件的cssclass中填入HideBar,就可以做到每个继承MasterPage或使用用户控件的页面都能正确显示图片了。
我想应该还有其它更好的办法,也希望有人能指点一二。

----------------------------------------------------------------------------------------------
集合
ArrayList:在添加项时动态调整大小,最适合用于在数据频繁改变时存储自定义对象类型,例如在执行频繁的插入和删除时
Hashtable:最适合于不会频繁改变的数据,特别适用于经常查询的数据
Queue(先进先出):在需要按顺序排序的数据时应该使用该集合
SortedList(有顺序的存储空间key/value):会使添加数据变的很慢,因为重新安排已有的项,以确保新的项目具有正确的顺序,适用于不会经

                                   常改变的数据
Stack(后进先出):需要按逆序排序的数据时应该使用该集合
StringCololection(字符串的集合):是强类型的ArrayList,用于存储具有任意顺序的字符串,并且用于频繁改变的字符串。
StringDictionary:强类型的HashTable,因此它用语需要排序的字符串时,并且这些字符串不会经常改变。
存储字符串时,有StringCololection、StringDictionary因为他们只存储字符串
----------------------------------------------------------------------------------------------------------------
lable1.text.split(splitChars.ToCharArray())
text返回String split是String类的方法,传递到字符串中的参数并不是splitChars变量本身,
而是已经转换成字符数组的splitChars(使用ToCharArray())
Split方法所需要的类型为字符数组

如果元素的个数不发生变化,最好使用数组,否则使用集合

使用属性而不用公有变量是因为面向对象的抽象原则,那些私有变量作为内部存储器,属性只是该类的用户用语访问内部变量的方法
-------------------------------------------------------------------------------------------------------------------
学习泛型 泛型集合  System.Collections.Generic
无论何时,在需要一个自定义类的集合时,最好使用泛型集合,提高代码的可读性减少潜在错误
private items as new list(of cartItem)
cartItem 这是一个自定义类,其中有变量
dim items as new list(of cartitem)

dim item as cartItem(...)
items.add(item)

该列表是个明确的数据类型,不能执行以下的操作
items.add("ffff")
-------------------------------------------------------------------------------------------------------------
partial class 不完全类表示在编译时后台代码文件和WEb Form被融合到一个类文件中


asp.net 2.0 用户代码----Microsoft Intermediate Language--Common Language Runtime---可执行代码
编译方法:
Pre-Runtime Compilation(运行前编译):后台代码文件被编译到一个程序集并被保存在\bin目录下。在需要时再编译Web Forms 和.aspx页面

Full Runtime compilation(完全运行时编译):后台代码文件和其他所有相关代码被放在APP_Code文件夹中,然后ASP.NET 2.0创建和维护对该

程序集(在运行时从这些文件中产生的) 的引用。

部署预编译(deployment pre-compilation)它是在部署之前对项目进行完全编译

posted @ 2006-10-16 16:34 javaca88 阅读(549) 评论(0) 编辑

posted @ 2006-10-16 10:20 javaca88 阅读(842) 评论(0) 编辑

w3c规范中getElementsByName是按着name属性进行检索的,而MS的IE却是按着id来检索。导致不能得到应该得到的Elements,为适应浏览器,我们可以做一下调整:
一、把需要用getElementsByName的name都加上id,且id和name相同。
二、用一个函数来适应浏览器,代码如下:
getElementsByName:function (name) {
              var 
returns document.getElementsByName(name
);
              if(
returns.length 0) return returns
;
              
returns 
= new Array();
              var 
document.getElementsByTagName('td'
);
              for(
0e.lengthi
++) {
                            if(
e[i].getAttribute("name") == name
) {
                                          
returns[returns.length] = e[i
];
                            }
              }
              return 
returns
;
}
posted @ 2006-10-16 09:08 javaca88 阅读(159) 评论(0) 编辑

javascript页面间传值    [转贴 2006-05-12 12:59:49 | 发表者: wrfwjn]   


这两窗口之间存在着关系.父窗口parent.htm打开子窗口son.htm
子窗口可以通过window.opener指向父窗口.这样可以访问父窗口的对象.
优点:取值方便.只要window.opener指向父窗口,就可以访问所有对象.
       不仅可以访问值,还可以访问父窗口的方法.值长度无限制.
缺点:两窗口要存在着关系.就是利用window.open打开的窗口.不能跨域.
      
Post.htm
<input type=text name=maintext>
<input type=button onclick="window.open('Read.htm')" value="Open">

Read.htm
<script language="javascript" >
//window.open打开的窗口.
//利用opener指向父窗口.
var parentText = window.opener.document.all.maintext.value;
alert(parentText);
</script>

posted @ 2006-10-16 09:06 javaca88 阅读(1973) 评论(0) 编辑

asp.net2.0中新增的gridview控件,是十分强大的数据展示控件。

  一、Gridview中的内容导出到Excel

  在日常工作中,经常要将gridview中的内容导出到excel报表中去,在asp.net 2.0中,同样可以很方便地实现将整个gridview中的内容导出到excel报表中去,下面介绍其具体做法:

  首先,建立基本的页面default.aspx

 
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
</div>


<asp:Button ID="BtnExport" runat="server" OnClick="BtnExport_Click"
Text="Export to Excel" />
</form>


  在default.aspx.cs中,写入如下代码:

 

protected void Page_Load(object sender, EventArgs e)
{
 if (!Page.IsPostBack)
 {
  BindData();
 }
}
private void BindData()
{
 string query = "SELECT * FROM customers";
 SqlConnection myConnection = new SqlConnection(ConnectionString);
 SqlDataAdapter ad = new SqlDataAdapter(query, myConnection);
 DataSet ds = new DataSet();
 ad.Fill(ds, "customers");
 GridView1.DataSource = ds;
 GridView1.DataBind();
}

public override void VerifyRenderingInServerForm(Control control)
{
 // Confirms that an HtmlForm control is rendered for
}

protected void Button1_Click(object sender, EventArgs e)
{
 Response.Clear();
 Response.AddHeader("content-disposition","attachment;filename=FileName.xls");
 Response.Charset = "gb2312";
 Response.ContentType = "application/vnd.xls";
 System.IO.StringWriter stringWrite = new System.IO.StringWriter();
 System.Web.UI.HtmlTextWriter htmlWrite =new HtmlTextWriter(stringWrite);

 GridView1.AllowPaging = false;
 BindData();
 GridView1.RenderControl(htmlWrite);

 Response.Write(stringWrite.ToString());
 Response.End();
 GridView1.AllowPaging = true;
 BindData();
}
protected void paging(object sender,GridViewPageEventArgs e)
{
 GridView1.PageIndex = e.NewPageIndex;
 BindData();
}


  在上面的代码中,我们首先将gridview绑定到指定的数据源中,然后在button1的按钮(用来做导出到EXCEL的)的事件中,写入相关的代码。这里使用Response.AddHeader("content-disposition","attachment;filename=exporttoexcel.xls");中的filename来指定将要导出的excel的文件名,这里是exporttoexcel.xls。要注意的是,由于gridview的内容可能是分页显示的,因此,这里在每次导出excel时,先将gridview的allowpaging属性设置为false,然后通过页面流的方式导出当前页的gridview到excel中,最后再重新设置其allowpaging属性。另外要注意的是,要写一个空的VerifyRenderingInServerForm方法(必须写),以确认在运行时为指定的ASP.NET 服务器控件呈现HtmlForm 控件。

  二、访问gridview中的各类控件

  在gridview中,经常要访问其中的各类控件,比如dropdownlist,radiobutton,checkbox等,下面归纳下在gridview中访问各类控件的方法。

  首先看下如何在gridview中访问dropdownlist控件。假设在一个gridviw中,展现的每条记录中都需要供用户用下拉选择的方式选择dropdownlist控件中的内容,则可以使用如下代码,当用户选择好gridview中的dropdownlist控件的选项后,点击按钮,则系统打印出用户到底选择了哪些dropdownlist控件,并输出它们的值。

 

public DataSet PopulateDropDownList()
{
 SqlConnection myConnection =new SqlConnection(ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString);
 SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM tblPhone", myConnection);
 DataSet ds = new DataSet();
 ad.Fill(ds, "tblPhone");
 return ds;
}


  上面的代码首先将数据库中tblphone表的数据以dataset的形式返回。然后在页面的itemtemplate中,如下设计

 

<ItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSource="<%# PopulateDropDownList() %>"
DataTextField="Phone" DataValueField = "PhoneID">
</asp:DropDownList>
</ItemTemplate>


  这里注意dropdownlist控件的datasource属性绑定了刚才返回的dataset(调用了populatedropdownlist()方法),并要注意设置好datatextfield和datavaluefield属性。

  然后,在button的事件中,写入以下代码:

 

protected void Button2_Click(object sender, EventArgs e)
{
 StringBuilder str = new StringBuilder();
 foreach (GridViewRow gvr in GridView1.Rows)
 {
  string selectedText = ((DropDownList)gvr.FindControl("DropDownList1")).SelectedItem.Text;
  str.Append(selectedText);
 }
 Response.Write(str.ToString());
}


  这里,我们用循环,来获得每一行的dropdownlist控件的值,并且将值添加到字符串中最后输出。

  接着,我们来看下如何访问gridview控件中的checkbox控件。经常在gridview控件中,需要给用户多项选择的功能,这个时候就需要使用checkbox控件。首先我们建立一个模版列,其中有checkbox如下:

 

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" DataKeyNames="PersonID" DataSourceID="mySource" Width="366px" CellPadding="4" ForeColor="#333333" GridLines="None">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="PersonID" HeaderText="PersonID" InsertVisible="False"
ReadOnly="True" SortExpression="PersonID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
<HeaderTemplate>
</HeaderTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>


  为了示意性地讲解如何得到用户选择的checkbox,可以增加一个按钮,当用户选择gridview中的选项后,点该按钮,则可以输出用户选了哪些选项,在按钮的CLICK事件中写入如下代码:

 

for (int i = 0; i < GridView1.Rows.Count; i++)
{
 GridViewRow row = GridView1.Rows[i];
 bool isChecked = ((CheckBox) row.FindControl("chkSelect")).Checked;
 if (isChecked)
 {
  str.Append(GridView1.Rows[i].Cells[2].Text);
 }
}
Response.Write(str.ToString());


  接下来,我们添加一个全选的选择框,当用户选择该框时,可以全部选择gridview中的checkbox.首先我们在headtemplate中如下设计:

 

<HeaderTemplate>
<input id="chkAll" onclick="javascript:SelectAllCheckboxes(this);" runat="server" type="checkbox" />
</HeaderTemplate>


  javascript部分的代码如下所示:

 

<script language=javascript>
function SelectAllCheckboxes(spanChk){
 var oItem = spanChk.children;
 var theBox=(spanChk.type=="checkbox")?spanChk:spanChk.children.item[0];
 xState=theBox.checked;
 elm=theBox.form.elements;
 for(i=0;i<elm.length;i++)
 if(elm[i].type=="checkbox" && elm[i].id!=theBox.id)
 {
  if(elm[i].checked!=xState)
  elm[i].click();
 }
}
</script>
三、gridview中删除记录的处理

  在gridview中,我们都希望能在删除记录时,能弹出提示框予以提示,在asp.net1.1中,都可以很容易实现,那么在asp.net 2.0中要如何实现呢?下面举例子说明,首先在HTML页面中设计好如下代码:

 
<asp:GridView DataKeyNames="CategoryID" ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound" OnRowDeleted="GridView1_RowDeleted" OnRowDeleting="GridView1_RowDeleting">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName" />
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" CommandArgument='<%# Eval("CategoryID") %>' CommandName="Delete" runat="server">Delete</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>


  在上面的代码中,我们设置了一个链接linkbutton,其中指定了commandname为"Delete",commandargument为要删除的记录的ID编号,注意一旦commandname设置为delete这个名称后,gridview中的GridView_RowCommand 和 GridView_Row_Deleting 事件都会被激发接者,我们处理其rowdatabound事件中:

 

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
 if (e.Row.RowType == DataControlRowType.DataRow)
 {
  LinkButton l = (LinkButton)e.Row.FindControl("LinkButton1");
  l.Attributes.Add('onclick", "javascript:return " + "confirm("是否要删除该记录? " +
  DataBinder.Eval(e.Row.DataItem, "id") + "')");
 }
}


  在这段代码中,首先检查是否是datarow,是的话则得到每个linkbutton,再为其添加客户端代码,基本和asp.net 1.1的做法差不多。

  之后,当用户选择了确认删除后,我们有两种方法对其进行继续的后续删除处理,因为我们将删除按钮设置为Delete,方法一是在row_command事件中写入如下代码:

 

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
 if (e.CommandName == "Delete")
 {
  int id = Convert.ToInt32(e.CommandArgument);
  // 删除记录的专门过程
  DeleteRecordByID(id);
 }
}


  另外一种方法是使用gridview的row_deletting事件,先在页面HTML代码中,添加<asp:GridView DataKeyNames="CategoryID" ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound" onRowDeleting="GridView1_RowDeleting">
然后添加row_deleting事件:

 

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
 int categoryID = (int) GridView1.DataKeys[e.RowIndex].Value;
 DeleteRecordByID(categoryID);
}


  要注意的是,这个必须将datakeynames设置为要删除记录的编号,这里是categoryid.

  小结

  在本文中,继续探讨了gridview控件的一些用法,如导出到excel,在删除记录时的处理,以及如何访问gridview中的控件等。

 
posted @ 2006-10-16 09:05 javaca88 阅读(80) 评论(0) 编辑

在asp.net 2.0中,gridview控件是十分不错的控件。有的时候,可能一个GRIDVIEW控件中
的各行都是文本框,如何一次性更新所有修改过的记录呢?有两种方法,一种是使用sqldatasource来更新
所有记录,但这个方法比较慢,因为每更新一条记录都要建立数据连接并执行updatecommand,会影响性能,
但还是先来看下实现方法:
 
<%@ Page Language="C#" %>
 
<script runat="server">
   
    void Button1_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            GridViewRow row = GridView1.Rows[i];
            SqlDataSource1.UpdateParameters[0].DefaultValue = ((TextBox)row.Cells[0].FindControl("TextBox2")).Text;
            SqlDataSource1.UpdateParameters[1].DefaultValue = ((TextBox)row.Cells[1].FindControl("TextBox3")).Text;
            SqlDataSource1.UpdateParameters[2].DefaultValue = GridView1.DataKeys[i].Value.ToString();
            SqlDataSource1.Update();
        }
    }   
   
</script>
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" Runat="server" DataSourceID="SqlDataSource1" DataKeyNames="CustomerID"
            AutoGenerateColumns="False">
            <Columns>
                <asp:TemplateField SortExpression="CustomerID" HeaderText="CustomerID">
                <ItemTemplate>
                    <asp:TextBox Runat="server" Text='<%# Bind("CustomerID") %>' ID="TextBox1"></asp:TextBox>
                </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField SortExpression="CompanyName" HeaderText="CompanyName">
                    <ItemTemplate>
                        <asp:TextBox Runat="server" Text='<%# Bind("CompanyName") %>' ID="TextBox2"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField SortExpression="ContactName" HeaderText="ContactTitle">
                    <ItemTemplate>
                        <asp:TextBox Runat="server" Text='<%# Bind("ContactTitle") %>' ID="TextBox3"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
        <asp:SqlDataSource ID="SqlDataSource1" Runat="server"
            SelectCommand="SELECT [CustomerID], [CompanyName], [ContactName], [ContactTitle] FROM [Customers]"
            UpdateCommand="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactTitle] = @ContactTitle WHERE [CustomerID] = @CustomerID"
            ConnectionString="<%$ ConnectionStrings:AppConnectionString1 %>">
            <UpdateParameters>
                <asp:Parameter Type="String" Name="CompanyName"></asp:Parameter>
                <asp:Parameter Type="String" Name="ContactTitle"></asp:Parameter>
                <asp:Parameter Type="String" Name="CustomerID"></asp:Parameter>
            </UpdateParameters>
        </asp:SqlDataSource>
        <asp:Button ID="Button1" Runat="server" Text="Button" OnClick="Button1_Click" />&nbsp;
   
    </div>
    </form>
</body>
</html>  另外一个方法是用组合SQL语句来进行的,速度比较快,原理也容易明白
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Text" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script runat="server">
   
    void Button1_Click(object sender, EventArgs e)
    {
        StringBuilder query = new StringBuilder();
       
        for (int i = 0; i < GridView1.Rows.Count; i++)
        {
            GridViewRow row = GridView1.Rows[i];
            string value1 = ((TextBox)row.Cells[0].FindControl("TextBox2")).Text.Replace("'","''");
            string value2 = ((TextBox)row.Cells[1].FindControl("TextBox3")).Text.Replace("'","''");
            string value3 = GridView1.DataKeys[i].Value.ToString();
 
            query.Append("UPDATE [Customers] SET [CompanyName] = '")
                .Append(value1).Append("' , [ContactTitle] = '")
                .Append(value2).Append("' WHERE [CustomerID] = '")
                .Append(value3).Append("';\n");
           
        }
 
        SqlConnection con = new SqlConnection(ConfigurationSettings.ConnectionStrings["AppConnectionString1"].ConnectionString);
        SqlCommand command = new SqlCommand(query.ToString(), con);
        con.Open();
        command.ExecuteNonQuery();
        con.Close();
    }
 
    void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            SqlConnection con = new SqlConnection(ConfigurationSettings.ConnectionStrings["AppConnectionString1"].ConnectionString);
            SqlCommand command = new SqlCommand("SELECT [CustomerID], [CompanyName], [ContactName], [ContactTitle] FROM [Customers]", con);
 
            con.Open();
            GridView1.DataSource = command.ExecuteReader();
            GridView1.DataBind();
            con.Close();
        }
    }
</script>
 
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" Runat="server" DataKeyNames="CustomerID"
            AutoGenerateColumns="False">
            <Columns>
                <asp:TemplateField SortExpression="CustomerID" HeaderText="CustomerID">
                <ItemTemplate>
                    <asp:TextBox Runat="server" Text='<%# Bind("CustomerID") %>' ID="TextBox1"></asp:TextBox>
                </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField SortExpression="CompanyName" HeaderText="CompanyName">
                    <ItemTemplate>
                        <asp:TextBox Runat="server" Text='<%# Bind("CompanyName") %>' ID="TextBox2"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField SortExpression="ContactName" HeaderText="ContactTitle">
                    <ItemTemplate>
                        <asp:TextBox Runat="server" Text='<%# Bind("ContactTitle") %>' ID="TextBox3"></asp:TextBox>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
      
        <asp:Button ID="Button1" Runat="server" Text="Button" OnClick="Button1_Click" />&nbsp;
   
    </div>
    </form>
</body>
</html>
posted @ 2006-10-16 09:04 javaca88 阅读(79) 评论(0) 编辑

ASP.NET2.0利用Gridview实现主从关系

首先我们来看下如何使用gridview实现一个 master -detail主从关系的应用,以实现一对多的关系,因为这是十分普遍的web应用。在asp.net 1.1中,可能要编写比较多的代码以实现这样的应用,但在asp.net 2.0中,已经可以很方便地实现这样的主从关系的应用了。下面分步来介绍:

  我们以sql server2000中的northwind数据库为例子进行介绍。该数据库中存在很多一对多关系的例子。这里,我们以products表和order detail表予以介绍。其中,我们实现这样的一个应用,通过dropdownlist下拉框,当用户每次选择一种商品时,可以马上通过gridview显示在所有的订单中,有哪些订单中曾经订购了该商品,两表构成典型的一对多关系。

  首先,我们要先将商品从product表中取出来,并绑定到dropdownlist中去。我们拖拉一个sqldatasource控件到窗体中去,命名为productListingDataSource,然后设置将product表的productid,productname字段取出,并按照productname进行排序,然后再拖拉一个dropdownlist控件到窗体中,点选该控件的smarttag智能标记,在弹出的菜单中,选择data source为刚才加入的sqldatasource的名称(就是productListingDataSource),并选择productname作为在下拉框中要显示的文本,同时,要将prodcutid设置为下拉框的选定值。如下图所示:
 

  接下来,我们再拖拉一个sqldatasource控件到窗体中去,命名为orderDetailsForProduct,在这个控件中,我们将其绑定到order detail表中,由于不需要返回所有的字段,所以我们只需要返回orderid,unitprice和quantity三个字段就可以了,并且我们需要与dropdownlist构成关联,所以我们要设置适当的sql语句.在asp.net 2.0中,这个也可以通过菜单的操作予以实现。

  我们在设置sqldatasource属性的时候,当遇到如下图所示的步骤时,点选"where "按钮.


  在点"where"按钮后,在弹出的菜单中(如下图所示),设置column为productid, 设置操作符operator为"=",设置source下拉框的值为control,表示要与来自控件的值进行绑定,选择后,再在右边的parameter properties属性窗口中的conrol id设置为刚才我们添加dropdownlist控件名的名称,最后,记得按"add"按钮,这样,就设置好sql语句了.
   
3
  最后,增加一个gridview控件,将其于刚才添加的名为orderDetailsForProduct的数据源控件绑定.这样就大功告成了.运行后,结果如下图所示:
  
4

5


  可以看到,当选择dropdownlist中的不同商品时,gridview会显示涉及该商品的不同订单的详细资料.程序的代码如下:

<form id="form1" runat="server">
 <div>
 <h2>You are Viewing Order Detail Information for Orders
that Have Included Shipments of the Selected Product</h2>
 <asp:SqlDataSource ID="productListingDataSource"
    Runat="server" ConnectionString=
     "<%$ ConnectionStrings:NWConnectionString %>"
     SelectCommand="SELECT [ProductID],
     [ProductName] FROM [Products]">
 </asp:SqlDataSource>
 <asp:DropDownList ID="productSelector" Runat="server"
   DataSourceID="productListingDataSource"
   DataTextField="ProductName" DataValueField="ProductID"
   AutoPostBack="True">
 </asp:DropDownList> 
 <asp:SqlDataSource ID="orderDetailsForProduct" Runat="server"
   SelectCommand="SELECT [OrderID], [ProductID], [UnitPrice],
   [Quantity] FROM [Order Details] WHERE ([ProductID] =
   @ProductID)"
   ConnectionString=
     "<%$ ConnectionStrings:NWConnectionString%>"
     DataSourceMode="DataReader">
     <SelectParameters>
 <asp:ControlParameter Name="ProductID"
Type="Int32"
   ControlID="productSelector"
   PropertyName="SelectedValue"></asp:ControlParameter>
 </SelectParameters>
 </asp:SqlDataSource><asp:GridView ID="orderDetailsGridView"
   Runat="server" DataSourceID="orderDetailsForProduct"
   AutoGenerateColumns="False" DataKeyNames="OrderID"
   BorderWidth="1px" BackColor="LightGoldenrodYellow"
   GridLines="None" CellPadding="2" BorderColor="Tan"
   ForeColor="Black">
 <FooterStyle BackColor="Tan"></FooterStyle>
 <PagerStyle ForeColor="DarkSlateBlue"
   HorizontalAlign="Center" BackColor="PaleGoldenrod">
 </PagerStyle>
 <HeaderStyle Font-Bold="True"
   BackColor="Tan"></HeaderStyle>
 <AlternatingRowStyle
   BackColor="PaleGoldenrod"></AlternatingRowStyle>
 <Columns>
  <asp:BoundField ReadOnly="True" HeaderText="Order ID"
    InsertVisible="False" DataField="OrderID"
    SortExpression="OrderID">
   <ItemStyle HorizontalAlign="Center"></ItemStyle>
  </asp:BoundField>
  <asp:BoundField HeaderText="Quantity"
    DataField="Quantity" SortExpression="Quantity"
    DataFormatString="{0:d}">
   <ItemStyle HorizontalAlign="Right"></ItemStyle>
  </asp:BoundField>
  <asp:BoundField HeaderText="Unit Price"
    DataField="UnitPrice" SortExpression="UnitPrice"
    DataFormatString="{0:c}">
    <ItemStyle HorizontalAlign="Right"></ItemStyle>
  </asp:BoundField>
 </Columns>
 <SelectedRowStyle ForeColor="GhostWhite"
  BackColor="DarkSlateBlue"></SelectedRowStyle>
</asp:GridView>
</div>
</form>

接下来,我们以另外一种更直观的方式,实现master-detail的主从关系.我们以northwind数据库的order表和order detail表为例子,实现这样的应用,当在gridview展示的所有订单中,当点选某一具体的订单,可以在右侧显示该订单的详细具体信息。

  步骤和上例子十分类似,先添加一个sqldatasource控件,命名为ordersDataSource,绑定到northwind数据库的orders表,只需要选择orderid,company,orderdate三个字段就可以了,然后添加一个gridview控件,选择控件右上角的"smart tag"智能标记,在弹出的菜单中,设置gridview控件为"enable paging"和"enable selection",即表示可以允许gridview分页和允许选择gridview中的每一行。

  接着选择"smart tag"标记,在弹出的菜单中选择"edit columns",对每一列进行具体设置,如下图,添加一个select类型的command field类型的字段,并设置其selecttext属性为"显示订单详细信息",

接下来,将该gridview控件绑定到ordersDataSource中去.再添加另外一个sqldatasource控件,命名为orderDetailsDataSource,按上文提到的方法,将其绑定到order detail表中,并且设置其where子句,通过order id,与order表中的orderid进行连接.这些可以通过菜单进行设置,如下图所示:
 

  最后,可以运行程序了.结果如下两图所示:
  


  可以清楚的看到,当选择左边的gridview的每一行时,如果点了"显示订单信息"的话,就会在右边显示这张订单的详细信息。

  此外,为了能使gridview能分页,则添加如下代码:

void orderGridView_PageIndexChanged(object sender, EventArgs e)
{
 orderGridView.SelectedIndex = -1;
}

  完整的代码如下:

<form id="form1" runat="server">
 <div style="width:50%;float:left;padding-right:10px;">
 <h2>Select an Order from the Left...</h2>
 <asp:SqlDataSource ID="ordersDataSource" Runat="server"
  SelectCommand="SELECT dbo.Orders.OrderID,
  dbo.Customers.CompanyName, dbo.Orders.OrderDate FROM
  dbo.Orders INNER JOIN dbo.Customers ON dbo.Orders.CustomerID = dbo.Customers.CustomerID"
  ConnectionString=
    "<%$ ConnectionStrings:NWConnectionString %>">
 </asp:SqlDataSource>
 <asp:GridView ID="orderGridView" Runat="server"
  DataSourceID="ordersDataSource" DataKeyNames="OrderID"
  AutoGenerateColumns="False" AllowPaging="True"
  BorderWidth="1px" BackColor="#DEBA84"
  CellPadding="3" CellSpacing="2" BorderStyle="None"
  BorderColor="#DEBA84"
  OnPageIndexChanged="orderGridView_PageIndexChanged">
 <FooterStyle ForeColor="#8C4510"
  BackColor="#F7DFB5"></FooterStyle>
  <PagerStyle ForeColor="#8C4510"
   HorizontalAlign="Center"></PagerStyle>
  <HeaderStyle ForeColor="White" Font-Bold="True"
   BackColor="#A55129"></HeaderStyle>
 <Columns>
  <asp:CommandField ShowSelectButton="True"
    SelectText="View Order Details"></asp:CommandField>
  <asp:BoundField HeaderText="Company"
    DataField="CompanyName"
    SortExpression="CompanyName"></asp:BoundField>
  <asp:BoundField HeaderText="Order Date"
    DataField="OrderDate" SortExpression="OrderDate"
    DataFormatString="{0:d}">
   <ItemStyle HorizontalAlign="Right"></ItemStyle>
  </asp:BoundField>
 </Columns>
 <SelectedRowStyle ForeColor="White" Font-Bold="True"
   BackColor="#738A9C"></SelectedRowStyle>
  <RowStyle ForeColor="#8C4510" BackColor="#FFF7E7"></RowStyle>
 </asp:GridView>
</div>
<div>
<h2>... and View the Order Details on the Right</h2>
<asp:SqlDataSource ID="orderDetailsDataSource" Runat="server"
 SelectCommand="SELECT dbo.[Order Details].OrderID,
 dbo.Products.ProductName, dbo.[Order Details].UnitPrice,
 dbo.[Order Details].Quantity, dbo.[Order Details].Discount
 FROM dbo.[Order Details] INNER JOIN dbo.Products
 ON dbo.[Order Details].ProductID = dbo.Products.ProductID
 WHERE dbo.[Order Details].OrderID = @OrderID"
 ConnectionString="<%$ ConnectionStrings:NWConnectionString %>">
<SelectParameters>
 <asp:ControlParameter ControlID="orderGridView"
  Name="OrderID" Type="Int32"
  PropertyName="SelectedValue" />
</SelectParameters>
</asp:SqlDataSource>

<asp:GridView ID="detailsGridView" Runat="server"
 DataSourceID="orderDetailsDataSource"
 AutoGenerateColumns="False" BorderWidth="1px"
 BackColor="#DEBA84" CellPadding="3"
 CellSpacing="2" BorderStyle="None" BorderColor="#DEBA84">
 <FooterStyle ForeColor="#8C4510" BackColor="#F7DFB5"></FooterStyle>
 <PagerStyle ForeColor="#8C4510" HorizontalAlign="Center"></PagerStyle>
 <HeaderStyle ForeColor="White" Font-Bold="True" BackColor="#A55129"></HeaderStyle>
 <Columns>
<asp:BoundField HeaderText="Product"
 DataField="ProductName"
 SortExpression="ProductName"></asp:BoundField>
<asp:BoundField HeaderText="Unit Price"
 DataField="UnitPrice" SortExpression="UnitPrice"
 DataFormatString="{0:c}">
 <ItemStyle HorizontalAlign="Right"></ItemStyle>
</asp:BoundField>
<asp:BoundField HeaderText="Quantity"
 DataField="Quantity" SortExpression="Quantity">
 <ItemStyle HorizontalAlign="Right"></ItemStyle>
</asp:BoundField>
<asp:BoundField HeaderText="Discount"
 DataField="Discount" SortExpression="Discount"
 DataFormatString="{0:P}">
<ItemStyle HorizontalAlign="Right"></ItemStyle>
</asp:BoundField>
</Columns>
<SelectedRowStyle ForeColor="White" Font-Bold="True"
 BackColor="#738A9C"></SelectedRowStyle>
<RowStyle ForeColor="#8C4510" BackColor="#FFF7E7"></RowStyle>
</asp:GridView>
</div>
</form>

posted @ 2006-10-16 08:55 javaca88 阅读(96) 评论(0) 编辑