您所在的位置: 程序员家园 -> 家园博客 ->
 
在哪里摔倒
就在哪里自己爬起来

用户登录

查  找

最新评论

最新留言

常用网站

网易邮箱 GMAIL  

百度搜索 MSDN

霏凡软件 BT精品

影视帝国 射 手 网

电驴下载 全 库 网

友情连接

茄菲的窝 冰冰博客

枫叶飘零 玫  瑰

ACEN 云 豹 子

统  计



Repeater和DataGrid相互嵌套三层及对第三层的控制
狼子 发表于 2005-6-30 23:29:00 阅读全文 | 回复(1) | 引用通告 | 编辑

原贴子在这里:http://www.tiantiansoft.com/bbs/dispbbs.asp?boardID=40&ID=90981

相关贴子在这里:http://www.tiantiansoft.com/bbs/dispbbs.asp?boardID=40&ID=91023

嗯,我是在Repeater1里,套了一个Repeater2,然后在Repeater2里,套了两个DataGrid,一共嵌套是三层。用Repeater1套Repeater2,是为了搞分组的显示,在Repeater2里套DataGrid,是想要给明细记录显示其它具体的信息。

在aspx页面里,我是这样子定义的:

<asp:repeater id="Repeater1" runat="server">
  <HeaderTemplate>
    <table width="600" border="1" align="center">
  </HeaderTemplate>
  <ItemTemplate>
    <tr>
      <td colspan="11">分组报头信息<asp:TextBox ID="MyId" CssClass="hiddeninput" Runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "d_iid") %>'></asp:TextBox></td>
    </tr>
    <asp:Repeater id="Repeater2" runat="server" OnItemCommand="Repeater2_ItemCommand" OnItemDataBound="Repeater2_ItemDataBound">
      <ItemTemplate>
        <tr align="center">
        <td>这个按钮就是我想要用来控制两个DataGrid的显示的按钮
          <asp:imagebutton id="Detail" CommandName="detail" CausesValidation="False" runat="server" ImageUrl="../images/plus.gif"></asp:imagebutton><asp:TextBox ID="txtPid" Runat="server" CssClass="hiddeninput" Text='<%# DataBinder.Eval(Container.DataItem,"pid") %>'></asp:TextBox>
        </td>
        <tr align="center">
          <td colspan="8">
            <asp:DataGrid id="DataGrid1" runat="server" Width="570px" AutoGenerateColumns="False">
            </asp:DataGrid>
            <asp:DataGrid id="DataGrid2" runat="server" Width="570px" AutoGenerateColumns="False">
            </asp:DataGrid>
          </td>
        </tr>
      </ItemTemplate>
    </asp:Repeater>
  </ItemTemplate>
<FooterTemplate>
    </table>
  </FooterTemplate>
</asp:repeater>

这里的东东,是我把所有具体信息都删除掉了的,只留下了有关的控件的相互关系的框架。

嗯,蓝色那一段,是很重要的。因为被嵌套的控件的数据的检索,是要在父级控件的ItemDataBound事件里检索的,可是被嵌套的控件在页面里是没有定义的,他们要在父级控件里用FindControl来取,所以他们的事件也要在程序里动态的绑定。关于On...这个,我在MSDN里查到的是“引发事件时会通过委托调用事件处理程序”,可是具体是嘛样子搞法的,我也没知道。我本来是在Repeater1的ItemDataBound事件里使用下面的语句来委托的:

MyRepeater.ItemDataBound+=new System.Web.UI.WebControls.RepeaterItemEventHandler(this.Repeater2_ItemDataBound);
MyRepeater.ItemCommand += new System.Web.UI.WebControls.RepeaterCommandEventHandler(this.Repeater2_ItemCommand);

但建立委托后,ItemCommand事件还是没法使用,所以我只好使用了OnItemCommand和OnItemDataBound,让他们自己搞。

下边看.cs文件,Repeater1的DataBind可以写在需要的地方,这里主要想说的是Repeater2和两个DataGrid的数据的检索,还有就是通过按钮控制DataGrid的属性

1、检索第二层的Repeater2:在Repeater1的ItemDataBound事件里绑定数据:

private void Repeater1_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
    {
      //检索具体项目
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
      {
        Repeater MyRepeater=(Repeater)e.Item.FindControl("Repeater2");
        if(MyRepeater!=null)
        {
          string diid,mysql;
          TextBox MyTextBox=(TextBox)e.Item.FindControl("MyId");
          if(MyLabel!=null)
          {
            diid=MyTextBox.Text.Trim();
            mysql="这里是检索数据时用的sql语句";
            mysql+=" from 表名 where d_iid=" + diid;
            //检索,我这里是把所有东东都提到NNLL.cs文件里的,所以直接调用里面的方法
            NNLL nnll=new NNLL();
            SqlConnection MyConnection=nnll.OpenConn();
            nnll.Repeater_Retrieve(this,MyConnection,MyRepeater,mysql);
            nnll.CloseConn(MyConnection);
          }
        }
      }
    }

因为Repeater2是用来显示Repeater1中每一条记录所对应的明细记录的,所以它需要从Repeater1里取条件,我在Repeater1里用了一个id=MyId的TextBox记录值,取值方法如红色那几段

2、检索第二层的两个DataGrid,在aspx页面里,已经定义了OnItemDataBound="Repeater2_ItemDataBound,所以这里只需要自定义Repeater2_ItemDataBound方法。嗯,这两个DataGrid,是用来显示明细项的具体其它信息的,所以同样要从当前的明细项里取条件,我用在Repeater2里加了一个id=txtPid的TextBox

protected void Repeater2_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
    {
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
      {
        //嵌套子Repeater的ItemDataBound事件
        TextBox MyTextBox=(TextBox)e.Item.FindControl("txtPid");
        string pid=null;
        if(MyTextBox!=null)
        {
          pid=MyTextBox.Text.Trim();
          //参与人员
          DataGrid MyDataGrid=(DataGrid)e.Item.FindControl("DataGrid1");
          if(MyDataGrid!=null) DataGrid_Retrieve(MyDataGrid,"boffin",pid);
          //文件
          MyDataGrid=(DataGrid)e.Item.FindControl("DataGrid2");
          if(MyDataGrid!=null) DataGrid_Retrieve(MyDataGrid,"file",pid);
        }
      }
    }

这里我用的是private,因为这个方法我要在aspx页面里调用

3、在第二层的Repeater2里,用按钮控制两个DataGrid的Visible属性。在aspx页面里,已经定义了OnItemCommand="Repeater2_ItemCommand",这里也是再自定义一个Repeater2_ItemCommand方法就成:

protected void Repeater2_ItemCommand(object source, System.Web.UI.WebControls.RepeaterCommandEventArgs e)
    {
      //嵌套子Repeater的ItemCommand事件
      if(e.CommandName=="detail")
      {
        //检索DataGrid
        DataGrid MyDataGrid=null;
        Repeater MyRepeater=null;
        MyRepeater=(Repeater)source;
        if(MyRepeater!=null)
        {
          MyDataGrid=(DataGrid)MyRepeater.Items[e.Item.ItemIndex].FindControl("DataGrid1");
          MyDataGrid.Visible=!(MyDataGrid.Visible);
          MyDataGrid=(DataGrid)MyRepeater.Items[e.Item.ItemIndex].FindControl("DataGrid2");
          MyDataGrid.Visible=!(MyDataGrid.Visible);
        }
      }
    }

使用事件自己的source参数,可以直接调用当前点击的按钮所在的Repeater控件,所以可以直接用它使用FindControl来取第三层的DataGrid

最后,嗯,我自己的总结就是,嗯,嵌套是没嘛关系的,我现在还没试过,我是想,如果我在第三层的DataGrid里也使用OnItemDataBound="DataGrid1_ItemDataBound"的话呢,应该也可以在第三层的DataGrid里搞一个模版列,再套第四层的其它数据控件,然后呢,用DataGrid1_ItemDataBound事件来检索它的。不过有个问题是,数据库在这里,虽然是一个页面,不过是没断的给打开又关闭的,每一层嵌套的控件检索数据时,都需要在它的父级的ItemDataBound事件里再连接一回数据库。

嗯,我的意思,呀,嘛样子表达好呢?

这样子来说,Repeater1里套着Repeater2的,在检索Repeater1的数据时,数据库是已经连接了的,而ItemDataBound事件呢,是每个Item都触发的,在Repeater1里显示了几条记录,ItemDataBound事件就被触发几回,那就相当于有几个Repeater2被检索过数据,而Repeater2检索时,又要再连接一回数据库,这里连接的数据库就是重复的了,对服务器来说是负担加重了。

剩下的是搞完后才发现这里没嘛东东技巧,用的就是事件的委托、FindControl还有ItemCommand事件的第一个参数object source,如果这些东东在一开始的时候就掌握好了的话呢,就用没着耗上我这么这么多的时间来搞了

回复:Repeater和DataGrid相互嵌套三层及对第三层的控制
メ冰枫ぱ雪发表评论于2005-7-2 1:16:00 个人主页 | 引用 | 返回 | 删除 | 回复
传说中的.net

发表评论:

    昵称:
    密码:
    主页:
    标题:
Powered by Oblog.