漫漫技术人生路

C#

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

公告

2006年10月27日 #

Protected Sub GridView1_RowCreated(ByVal sender As ObjectByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
        
If (e.Row.RowType = DataControlRowType.DataRow) Then
            
Dim bt1 As Button = CType(e.Row.FindControl("cart"), Button)
            bt1.CommandArgument 
= e.Row.RowIndex.ToString
            
Dim bt2 As Button = CType(e.Row.FindControl("favorite"), Button)
            bt2.CommandArgument 
= e.Row.RowIndex.ToString
        
End If

    
End Sub
posted @ 2006-10-27 16:42 javaca88 阅读(918) 评论(0) 编辑

http://blog.csdn.net/rootbin1/
<%@ Page language="C#" %>

<script runat="server">

  void CustomersGridView_RowCommand(Object sender, GridViewCommandEventArgs e)
  {
    // If multiple buttons are used in a GridView control, use the
    // CommandName property to determine which button was clicked.
    if(e.CommandName=="Add")
    {
      // Convert the row index stored in the CommandArgument
      // property to an Integer.
      int index = Convert.ToInt32(e.CommandArgument);
           
      // Retrieve the row that contains the button clicked
      // by the user from the Rows collection.
      GridViewRow row = CustomersGridView.Rows[index];
           
      // Create a new ListItem object for the customer in the row.    
      ListItem item = new ListItem();
      item.Text = Server.HtmlDecode(row.Cells[2].Text);
           
      // If the customer is not already in the ListBox, add the ListItem
      // object to the Items collection of the ListBox control.
      if (!CustomersListBox.Items.Contains(item))
      {
        CustomersListBox.Items.Add(item);
      }          
    }
  }

  void CustomersGridView_RowCreated(Object sender, GridViewRowEventArgs e)
  {
   
    // The GridViewCommandEventArgs class does not contain a
    // property that indicates which row's command button was
    // clicked. To identify which row's button was clicked, use
    // the button's CommandArgument property by setting it to the
    // row's index.
    if(e.Row.RowType == DataControlRowType.DataRow)
    {
      // Retrieve the LinkButton control from the first column.
      LinkButton addButton = (LinkButton)e.Row.Cells[0].Controls[0];
         
      // Set the LinkButton's CommandArgument property with the
      // row's index.
      addButton.CommandArgument = e.Row.RowIndex.ToString();
    }

  }
   
</script>

<html>
  <body>
    <form runat="server">
       
      <h3>GridView RowCommand Example</h3>
           
      <table width="100%">        
        <tr>               
          <td width="50%">
                   
            <asp:gridview id="CustomersGridView"
              datasourceid="CustomersSource"
              allowpaging="true"
              autogeneratecolumns="false"
              onrowcommand="CustomersGridView_RowCommand"
              onrowcreated="CustomersGridView_RowCreated" 
              runat="server">
               
              <columns>
                <asp:buttonfield buttontype="Link"
                  commandname="Add"
                  text="Add"/>
                <asp:boundfield datafield="CustomerID"
                  headertext="Customer ID"/>
                <asp:boundfield datafield="CompanyName"
                  headertext="Company Name"/>
                <asp:boundfield datafield="City"
                  headertext="City"/>        
              </columns>
               
            </asp:gridview>
                   
          </td>
                   
          <td valign="top" width="50%">
                   
            Customers: <br/>
            <asp:listbox id="CustomersListBox"
              runat="server"/>
                   
          </td> 
        </tr>     
      </table>
           
      <!-- This example uses Microsoft SQL Server and connects  -->
      <!-- to the Northwind sample database. Use an ASP.NET     -->
      <!-- expression to retrieve the connection string value   -->
      <!-- from the Web.config file.                            -->
      <asp:sqldatasource id="CustomersSource"
        selectcommand="Select [CustomerID], [CompanyName], [City] From [Customers]"
        connectionstring="<%$ ConnectionStrings:NorthWindConnectionString%>"
        runat="server"/>
           
    </form>
  </body>
</html>

posted @ 2006-10-27 10:50 javaca88 阅读(207) 评论(0) 编辑

子窗口和父窗口交互的内容,基本上无非就是把子窗口的信息传递给父窗口,并且关闭自己等等,或者是父窗口把自己的信息传递给子窗口等等。

1。父窗口传递信息给子窗口

看代码实例:
<script language=javascript>

function outPut()
{
 //获取父窗口的文本信息赋值给text
 var text = document.abc.text.value;
 //打开子窗口,并且把操作句柄赋值给win变量,以下所有操作都是针对win对象的
 var win = window.open("","mywin", "menubar=no,width=400,height=100,resizeable=yes");
 //输出基本信息
 win.document.writeln("<title>输出结果</title>");
 win.document.writeln("你的信息是:<p>");
 //输出从父窗口获取的信息
 win.document.writeln(text);
 win.document.close();
 win.focus();
}
</script>

<form name=abc method=post>
<input type=text name=text size=50>
//调用上面的函数
<input type=button value=提交 onClick="outPut()">

</form>


2。子窗口传递参数给父窗口

我们对上面的代码进行改造:

<script language=javascript>

function outPut()
{
 var text = document.abc.text.value;
 var win = window.open("","mywin", "menubar=no,width=400,height=100,resizeable=yes");
 win.document.writeln("<title>输出结果</title>");
 win.document.writeln("你的信息是:<p>");
 win.document.writeln(text);
 win.document.writeln("<input type=text name=child value=子窗口信息>");

 //对子窗口本身操作,使用self对象,对父窗口操作使用opener对象,这是关键
 //把子窗口中表单的值回传给父窗口,取代父窗口表单以前的值,然后关闭子窗口
 win.document.writeln("<input type=button value=关闭自己 onClick='window.opener.abc.text.value=self.child.value;self.close()'>");
 //可以控制关闭父窗口
 win.document.writeln("<input type=button value=关闭父窗口 onClick='window.opener.opener=null;window.opener.close()'>");
 //刷新父窗口
 win.document.writeln("<input type=button value=刷新父窗口 onClick='window.opener.location.reload()'>");

 win.document.close();
 win.focus();
}
</script>

<form name=abc method=post>
<input type=text name=text size=50>
<input type=button value=提交 onClick="outPut()">

</form>


3。不是同页面的子窗口和父窗口交互

假设我们涉及到外部程序,比如php、asp等等,那么我们处理的可能是两个页面,比如,上传功能,我们就是需要打开一个新页面,然后再把新页面中的值传递给父页面。

局部代码实例:

<input type="input" value="" name="input_tag" id = "input_tag" onKeyUp="clearPreTagStyle()" size="40">
<input type="hidden" value="0" name="tagid" id="tagid">
<input type="button" value="标签" onclick="popUpWindow('tag.php?tag='+escape(document.tryst_form.input_tag.value))">

以上是父窗口的部分代码,里面的popUpWindow是封装好的window.open函数,所以理解面面的tag.php是另外一个页面就可以,我们需要把当前表单中的值提交给tag.php页面去处理。


tag.php部分代码:

查询标签结果:
<a href="#" name="tag_1">生活</a><a href="#" onclick="opener.document.tryst_form.input_tag.value = document.tag_1.innerHTML">加入该标签</a>

<a href="#" name="tag_2">生活秀</a><a href="#" onclick="opener.document.tryst_form.input_tag.value = document.tag_2.innerHTML">加入该标签</a>

这个就是我们的子窗口,我们要把tag_1和tag_2返回到子窗口中,虽然他们不是同一个页面。这里有个知识点,就是我们如何获取连接中的值,我们使用innerHTML属性:document.tag_2.innerHTML 这个就是我们获取了tag_2的值“生活秀”,我们也能使用其他方法获取,比如:document.all.tag_2.innerHTML,或者this.innerHTML就是指本身的链接的值。

访问父窗口也是使用opener对象来处理:opener.document.tryst_form.input_tag.value,就能够改变父窗口的值。


基本我目前了解就是如此,以后有东西继续添加。
--------------------------------------------------------------------------------------------------------------------------
Web开发中适当运用一些弹出子窗口有很多好处,可以节省页面设计代价,获得好的用户体验,在最近项目开发中我遇到了几个父子窗口的问题,现在整理给大家,希望有所帮助.
              
   情景一: 打开某一子窗口, 子窗口中任一按钮点击时候不能弹出新页面,进行完操作后,关闭该子窗口,刷新父窗口.        
       
                 1: 页面A:父窗口,其中有一个打开子窗口的链接,<a  href="#"onclick="open()
">页面C</a>
                      A中有如下js代码:

<script language="JavaScript">
   
function open()
   {
     window
.showModalDialog("页面B");
   }
</script>

                2: 页面B,此为中间页,起过渡作用
                     B html 代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>**</title>
</head>

<frameset rows="0,*">
    
<frame src="about:blank">
    
<frame src="页面C">
  
</frameset><noframes></noframes>
</html>

                 3:页面C ,要打开的子窗口.
                    它关闭时候刷新父窗口很简单,只要把A中
                    <a  href="#"onclick="open()">页面C</a>  改为
                    <a  href="页面A"onclick="open()">页面C</a>

    情景二:打开某一需要用到activex控件子窗口, 子窗口中任一按钮点击时候不能弹出新页面,进行完操作后,关闭该子窗口,刷新父窗口.  
                  此时候就不能用 window.showModalDialog()事件打开模式对话框了因为activex控件会报错,必须用window.open()
 
                  1: 页面A:父窗口,其中有一个打开子窗口的链接,<a  href="#"onclick="open()">页面B</a>
                      A中有如下js代码.

                  2: 页面B,要打开的子窗口,关闭时候触发window.opener.location.reload();window.close();即可刷新父窗口并且关闭子窗口.

   
     情景三:打开某一子窗口,   让用户选择要添加的东东,譬如要添加到文章里的相片选择后关闭子窗口,然后选择的东东出现在父窗口里.
                    在下图中,我点击"添加照片"链接然后弹出子窗口,在子窗口中选择后点击"添加照片"按钮,子窗口自动关闭,并且父窗口"已添加照片:"下面列出了我选择的照片。

        
      
            

               实现方法:类似情景一需要中间页面B , 只是子窗口C中点击"添加按钮"时触发的js事件中,除了获得选中的checkbox的值外,还要把获得的值回传给父窗口,传值回去的代码如下.
              

<script language="JavaScript">
function open()
 {
   window
.open("页面B",'upload', 'height=400, width=420, top=0, left=0, toolbar=no, menubar=no,scrollbars=no, resizable=no,location=no, status=no');
 }
</script>

 

window.parent.returnValue="选中的checkbox";
               window
.parent.close();


              而父窗口要捕获此值就要在情景一中所说的open()事件中添加获得返回值 

<script language="JavaScript">
  
function open()
   {
         
var str=window.showModalDialog("页面C");
         
if(str!=null)  
       {              
          picobj
.innerHTML+=str; 
          
       }
    }
</script>

               注意这里的str是获取的返回值, 而picobj是你要显示被选择东东所放位置的div的id ,这里是<div id=picobj></div>

posted @ 2006-10-27 08:36 javaca88 阅读(1818) 评论(0) 编辑

实际上Eval方法是TemplateControl的,而System.Web.UI.Page和System.Web.UI.UserControl都继承于TemplateControl,所以我们可以在Page和UserControl上直接调用个方法。

Page.Eval方法可以帮助我们更好的撰写数据绑定表达式,在ASP.NET 1.x时代,数据绑定表达式的一般形式是:
<%# DataBinder.Eval( Container , “DataItem.Name”) %>
而在ASP.NET 2.0中,同样的代码,我们可以这样写:
<%# Eval( “Name” )%>
ASP.NET 2.0是怎么实现的呢?我们先从Eval方法来研究,通过反射.NET Framework 2.0类库的源代码,我们可以看到这个方法是这样实现的:
protected internal object Eval(string expression)
{
      this.CheckPageExists();
      return DataBinder.Eval(this.Page.GetDataItem(), expression);
}
第一行我们不必管,这是检查调用的时候有没有Page对象的,如果没有则会抛出一个异常。
关键是第二行:
      return DataBinder.Eval(this.Page.GetDataItem(), expression);
Page.GetDataItem()也是2.0中新增的一个方法,用途是正是取代ASP.NET 1.x中的Container.DataItem。
看来不摸清楚GetDataItem()方法,我们也很难明白Eval的原理。GetDataItem的实现也很简单:
public object GetDataItem()
{
      if ((this._dataBindingContext == null) || (this._dataBindingContext.Count == 0))
      {
            throw new InvalidOperationException(SR.GetString("Page_MissingDataBindingContext"));
      }
      return this._dataBindingContext.Peek();
}
我们注意到了有一个内部对象_dataBindingContext,通过查源代码发现这是一个Stack类型的东西。所以他有Peek方法。而这一段代码很容易看懂,先判断这个Stack是否被实例化,然后,判断这个Stack里面是不是有任何元素,如果Stack没有被实例化或者没有元素则抛出一个异常。最后是将这个堆栈顶部的元素返回。
ASP.NET 2.0用了一个Stack来保存所谓的DataItem,我们很快就查到了为这个堆栈压元素和弹出元素的方法:Control.DataBind方法:
protected virtual void DataBind(bool raiseOnDataBinding)
{
      bool flag1 = false;//这个标志的用处在上下文中很容易推出来,如果有DataItem压栈,则在后面出栈。
      if (this.IsBindingContainer)//判断控件是不是数据绑定容器,实际上就是判断控件类是不是实现了INamingContainer
      {
            bool flag2;
            object obj1 = DataBinder.GetDataItem(this, out flag2);//这个方法是判断控件是不是有DataItem属性,并把它取出来。
            if (flag2 && (this.Page != null))//如果控件有DataItem
            {
                  this.Page.PushDataBindingContext(obj1);//把DataItem压栈,PushDataBindingContext就是调用_dataBindingContext的Push方法
                  flag1 = true;
            }
      }
      try
      {
            if (raiseOnDataBinding)//这里是判断是不是触发DataBinding事件的。
            {
                  this.OnDataBinding(EventArgs.Empty);
            }
            this.DataBindChildren();//对子控件进行数据绑定,如果这个控件有DataItem,则上面会将DataItem压入栈顶,这样,在子控件里面调用Eval或者GetDataItem方法,就会把刚刚压进去的DataItem给取出来。
      }
      finally
      {
            if (flag1)//如果刚才有压栈,则现在弹出来。
            {
                  this.Page.PopDataBindingContext();//PopDataBindingContext就是调用_dataBindingContext的Pop方法
            }
      }
}
至此,我们已经可以完全了解ASP.NET 2.0中GetDataIten和Eval方法运作的原理了,下一次我打算研究ASP.NET 2.0中的新的Bind语法。


有提供Bind语法资料的和提出好建议的酌情给分,up、顶等分会很少,接分者无分。


作者:asen
发表时间:2006-4-4 10:22:14

我比较追求程序效率,想问一下各位
关于asp.net 2.0页面里的数据绑定方式是用Eval效率高,还是1.1里公认的((DataRowView)Container.DataItem)["某某某"]效率高呢?


作者:asen
发表时间:2006-4-4 10:22:28

这个也不是这样说..
asp.net中数据绑定有许多种..
如:简单属性
集合
表达式
方法调用..
还有.包括你所说的DataBinder.Eval()....
它们都可以进行数据绑定..
这个你得看..在哪些地方.适合用哪种绑定效率高.你就使用哪种.


作者:asen
发表时间:2006-4-4 10:22:42

毋庸置疑的是强类型转换Container的效率是最高的,Eval最终是调用DataBinder.Eval方法,DataBinder.Eval是采用反射来获取数据的,这显然不如强类型数据转换。

我们可以比较一下各种方法:

((Type) Container.DataItem).Property
这种方法效率是最高的,因为不存在任何反射。

其次是:
((Type) GetDataItem()).Property
这种方法效率差的原因在于多了一个Stack的Peek操作,当然,实际上这点儿差别可以忽略。

最后是:
Eval或者DataBinder.Eval,这两种方法都使用反射来查找属性或者索引器成员,效率大打折扣。

另外一个值得注意的问题是,所有实现了INamingContainer接口的Control,都应该实现IDataItemContainer接口,因为在Control.DataBind的时候,如果发现控件实现了INamingContainer接口,就会试图去寻找它的DataItem,如果这个控件没有实现IDataItemContainer,则DataBinder.GetDataItem方法会使用反射看看控件有没有一个叫做DataItem的属性成员,显然这不是我们希望看到的。
其实ASP.NET还有一个标记接口:INonBindingContainer,实现了INamingContainer接口的控件可以选择同时实现这个来命令ASP.NET不去寻找DataItem,可是很可惜,不知道微软出于什么目的,这个接口是internal的……

其实效率方面不必太重视了,Eval表达式很好看的,即使有那么极端的重视效率,GeDataItem也是不错的选择。


作者:asen
发表时间:2006-4-4 10:23:01

see http://localhost/QuickStartv20/aspnet/doc/data/templates.aspx#twowaybind
双向数据绑定
与 DetailsView 控件一样,FormView 通过其关联的数据源控件支持自动 Update、Insert 和 Delete 操作。若要定义编辑或插入操作的输入 UI,可在定义 ItemTemplate 的同时定义 EditItemTemplate 或 InsertItemTemplate。在本模板中,您将对输入控件(如 TextBox、CheckBox 或 DropDownList)进行数据绑定,以绑定到数据源的字段。但是,这些模板中的数据绑定使用“双向”数据绑定语法,从而允许 FormView 从模板中提取输入控件的值,以便传递到数据源。这些数据绑定使用新的 Bind(fieldname) 语法而不是 Eval。

重要事项: 使用 Bind 语法进行数据绑定的控件必须设置有 ID 属性。

<asp:FormView DataSourceID="ObjectDataSource1" 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>
在对 GridView 或 DetailsView 执行更新或插入操作时,如果该控件的列或字段定义了 BoundField,GridView 或 DetailsView 负责创建 Edit 或 Insert 模式中的输入 UI,以便它能自动提取这些输入值以传递回数据源。由于模板包含任意的用户定义的 UI 控件,因此,需要使用双向数据绑定语法,这样 FormView 等模板化控件才能知道应从模板中提取哪些控件值以用于更新、插入或删除操作。在 EditItemTemplate 中仍然可以使用 Eval 语法进行不传递回数据源的数据绑定。另请注意,FormView 与 DetailsView 和 GridView 一样,支持使用 DataKeyNames 属性保留主键字段(即使这些字段并未呈现)的原始值以传递回更新/插入操作。

FormView 支持使用 DefaultMode 属性指定要显示的默认模板,但在默认情况下,FormView 以 ReadOnly 模式启动并呈现 ItemTemplate。若要启用用于从 ReadOnly 模式转换为 Edit 或 Insert 模式的 UI,可以向模板添加一个 Button 控件,并将其 CommandName 属性设置为 Edit 或 New。可以在 EditItemTemplate 内添加 CommandName 设置为 Update 或 Cancel 的按钮,以用于提交或中止更新操作。类似地,也可以添加 CommandName 设置为 Insert 或 Cancel 的按钮,以用于提交或中止插入操作。

下面的示例演示一个定义了 ItemTemplate 和 EditItemTemplate 的 FormView。ItemTemplate 包含使用 Eval(单向)绑定的控件,而 EditItemTemplate 包含一个使用 Bind 语句双向绑定的 TextBox 控件。主键字段 (PhotoID) 是使用 DataKeyNames 属性在视图状态中进行往返的。FormView 包含用于在其模板之间进行切换的命令按钮。


C# Two-Way Databinding in a FormView Edit Template
 

通过使用添加到 Columns 或 Fields 集合的 TemplateField,GridView 和 DetailsView 还支持模板化 UI。TemplateField 支持使用 ItemTemplate、EditItemTemplate 和 InsertItemTemplate(仅 DetailsView)指定这些控件的不同呈现模式中的字段 UI。与上面的 FormView 示例一样,EditItemTemplate 或 InsertItemTemplate 中的双向绑定允许 GridView 或 DetailsView 从这些模板中的控件提取值。TemplateField 的常见用途是向 EditItemTemplate 添加验证程序控件,用于 GridView 或 DetailsView 操作的声明性验证。下面的示例演示这种方法的一个示例。有关 ASP.NET 中可用的验证控件的更多信息,请参考本教程的“验证窗体输入控件”部分。


C# Validation in a GridView Edit Template
 

TemplateField 的另一个用途是自定义输入控件,这种控件用于输入 GridView 或 DetailsView 列/字段值。例如,可以将 DropDownList 控件放在 TemplateField 的 EditItemTemplate 中,以允许从预定义的值列表进行选择。下面的示例演示这种方法。注意,本例中的 DropDownList 与它自己的数据源控件进行了数据绑定,以便动态地获取该列表的值。


C# DropDownList in a GridView Edit Template


作者:asen
发表时间:2006-4-4 10:23:15

ASP.NET 2.0 改进了模板中的数据绑定,将数据绑定语法由完整的 v1.x 语法 DataBinder.Eval(Container.DataItem, fieldname) 简化为 Eval(fieldname)。与 DataBinder.Eval 一样,Eval 方法也接受一个可选的 formatString 参数。缩写的 Eval 语法与 DataBinder.Eval 的不同之处,在于 Eval 根据最近的容器对象(在上面的示例中为 DataListItem)的 DataItem 属性自动解析字段,而 DataBinder.Eval 接受该容器的一个参数。因此,Eval 仅在数据绑定控件的模板中使用,而不能在“页”级别使用。当然,ASP.NET 2.0 页继续支持 DataBinder.Eval,因此它可用于简化的 Eval 语法不受支持的场合。 <asp:DataList DataSourceID="ObjectDataSource1" runat="server">
  <ItemTemplate>
    <asp:Image ImageUrl='<%# Eval("FileName", "images/thumbs/{0}") %>' runat="server"/>
    <asp:Label Text='<%# Eval("Caption") %>' runat="server"/>
  </ItemTemplate>
</asp:DataList>


作者:asen
发表时间:2006-4-4 10:23:36

((DataRowView)Container.DataItem)["某某某"] 的效率要比 <%# DataBinder.Eval( Container , “DataItem.Name”) %> 高很多。

而 <%# Eval( “Name” )%> 比 <%# DataBinder.Eval( Container , “DataItem.Name”) %> 还要多一步(多一层函数)。效率可想而知了。

当然也可能 2.0 会做什么优化也说不定呢。

posted @ 2006-10-27 08:24 javaca88 阅读(959) 评论(1) 编辑