上个问题地址是这里
http://community.csdn.net/Expert/topic/3518/3518267.xml?temp=5.575198E-02repeater控件已经可以实现我的要求了,但我发现要使用这个自定义repeater的话必须在使用的页面的.cs文件中使用ItemDataBound 来关联句柄,比如
//声明控件
protected System.Web.UI.WebControls.Repeater rptF;Page_Load中
rptF.DataSource = ……;
rptF.ItemDataBound +=new RepeaterItemEventHandler(rptF_ItemDataBound);
rptF.DataBind();private void rptF_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
      //repeater是我那个自定义控件
      repeater rptSon = (repeater)e.Item.FindControl("rptSon");      rptSon.DataBind();
    }
我想问的是能实现在使用自定义控件的时候不用ItemDataBound吗?如果能的话需要在自定义控件中怎么改呢?谢谢

解决方案 »

  1.   

    you shouldn't need to, since DataBind is called automatically by the container object, in your case, for example1. MySpace.cs:using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    using System.Data.SqlClient;
    using System.Data;namespace MySpace
    { [DefaultProperty("Text"), 
    ToolboxData("<{0}:repeater runat=server></{0}:repeater>")]
    public class repeater : System.Web.UI.WebControls.Repeater, INamingContainer
    {
    private string fId;

    [Bindable(true), 
    Category("Appearance"), 
    DefaultValue("")] 
    public string FId 
    {
    get
    {
    return fId;
    } set
    {
    fId = value;
    }
    } public override void DataBind()
        {
            if (fId != null && fId.Length > 0)
    {
    //I modify the following for testing purpose
           SqlConnection cn = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=;");
           DataTable dt = new DataTable("authors");
    SqlCommand cmd = new SqlCommand("select * from authors where au_lname = @name", cn);
    cmd.Parameters.Add("@name", fId);
           SqlDataAdapter sda = new SqlDataAdapter(cmd);
           sda.Fill(dt);
          
          this.DataSource = dt;
    }       base.DataBind();
        }
         }
    }2. TestRepeater.aspx:<%@ Page Language="c#" %>
    <%@ Import Namespace="System.Data" %><%@ Register TagPrefix="cc" Assembly="MySpace" Namespace="MySpace" %>
    <script runat="server">
    void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack)
      {
       string[] s = {"a","b","c"};
       Repeater1.DataSource = s;
       Repeater1.DataBind();
      }
    }   
    </script>    <form runat="server">
            <asp:repeater id="Repeater1" runat="server">

                <itemtemplate>
                   <%# Container.DataItem%>
                    <cc:repeater id="childRepeater" runat="server" fId="White">
                        <ItemTemplate>
                            ***<%# DataBinder.Eval(Container.DataItem, "au_fname") %>**** 
                        </ItemTemplate>
                    </cc:repeater>
                   
                </itemtemplate>
            </asp:repeater>
           <asp:Button id="btn" runat='server' Text='Refresh' />
        </form>
      

  2.   

    可是我如果不用ItemDataBound的话,不出循环结果呀,您看看我的代码有问题吗?
    repeater.csusing System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    using System.Data.SqlClient;
    using System.Data;namespace MyControl
    {
    /// <summary>
    /// 继承自Repeater控件的自定义控件,可以根据属性FID来生成控件内循环的内容
    /// </summary>
    [DefaultProperty("Text"), 
    ToolboxData("<{0}:repeater runat=server></{0}:repeater>")]
    public class repeater : System.Web.UI.WebControls.Repeater
    {
        private string table;
        private string field;
    private string fId; public string Table 
    {
    get
    {
    return table;
    } set
    {
    table = value;
    }
    }    public string Field 
        {
          get
          {
            return field;
          }      set
          {
            field = value;
          }
        }    public string FId 
        {
          get
          {
            return fId;
          }      set
          {
            fId = value;
          }
        }    protected override void CreateChildControls()
        {
          Repeater rptSon = new Repeater();      rptSon.DataBind();      Controls.Add(rptSon);
        }    public override void DataBind()
        {
          if (fId != null && fId.Length > 0 && table != null && table.Length > 0 && field != null && field.Length > 0)
          {
            SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]);        DataTable dt = new DataTable("dsTable");
            SqlDataAdapter sda = new SqlDataAdapter("select * from " + table + " where " + field + " = " + fId,cn);
            sda.Fill(dt);        this.DataSource = dt;        sda.Dispose();
            dt.Dispose();
            cn.Close();
            cn.Dispose();
          }      base.DataBind();
        }
      }
    }test.aspx
    <%@ Register TagPrefix="MyControl" NameSpace="MyControl" Assembly="MyControl"%>
    <%@ Page language="c#" Codebehind="test.aspx.cs" AutoEventWireup="false" Inherits="MyControl.test" codePage="65001"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <html>
      <head>
        <title>test</title>
      </head>
      <body ms_positioning="FlowLayout">
        <form id="Form1" method="post" runat="server">
          <table border="1"><asp:repeater id="rptF" runat="server">
              <itemtemplate>
                <tr>
                  <td><%# DataBinder.Eval(Container.DataItem, "class_Name") %></td>
                </tr>
                <tr>
                  <td>
                    <!---子循环开始---->
                    <table>
                      <netforum:repeater id="rptSon" runat="server" table="f_class" Field="class_related_id" fid='<%# DataBinder.Eval(Container.DataItem, "class_id") %>'>
                        <itemtemplate>
                          <tr>
                            <td>
                              <%# DataBinder.Eval(Container.DataItem, "class_name") %>
                            </td>
                          </tr>
                        </itemtemplate>
                      </netforum:repeater>
                    </table>
                    <!---子循环结束---->
                  </td>
                </tr>
              </itemtemplate>
            </asp:repeater></table></form>  </body>
    </html>test.aspx.cs
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Data.SqlClient;
    using System.Xml;
    using NetForum.Components.Control;namespace MyControl
    {
    /// <summary>
    /// test 的摘要说明。
    /// </summary>
    public class test : System.Web.UI.Page
    {
        protected System.Web.UI.WebControls.Repeater rptF;
      
        private void Page_Load(object sender, System.EventArgs e)
        {
          System.Data.SqlClient.SqlConnection cn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["conn"]);
          System.Data.SqlClient.SqlCommand sc = new SqlCommand("select * from f_class where class_related_id=0",cn);
          DataTable dt = new DataTable("dsTable");
          cn.Open();
          rptF.DataSource = sc.ExecuteReader();
          rptF.DataBind();
          cn.Close();
        } #region Web 窗体设计器生成的代码
    override protected void OnInit(EventArgs e)
    {
    //
    // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
    //
    InitializeComponent();
    base.OnInit(e);
    }

    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {    
          this.Load += new System.EventHandler(this.Page_Load);    }
        #endregion
      }
    }
      

  3.   

    remove protected override void CreateChildControls()
        {
          Repeater rptSon = new Repeater();      rptSon.DataBind();      Controls.Add(rptSon);
        }read/try my code carefully, to see 子循环, try<%@ Page Language="c#" %>
    <%@ Import Namespace="System.Data" %><%@ Register TagPrefix="cc" Assembly="MySpace" Namespace="MySpace" %>
    <script runat="server">
    void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack)
      {
       string[] s = {"a","b","c"};
       Repeater1.DataSource = s;
       Repeater1.DataBind();
      }
    }   
    </script>    <form runat="server">
            <asp:repeater id="Repeater1" runat="server">

                <itemtemplate>
                   <%# Container.DataItem%>
                    <cc:repeater id="childRepeater" runat="server" fId="Ringer">
                        <ItemTemplate>
                            ***<%# DataBinder.Eval(Container.DataItem, "au_fname") %>**** 
                        </ItemTemplate>
                    </cc:repeater>
                   
                </itemtemplate>
            </asp:repeater>
           <asp:Button id="btn" runat='server' Text='Refresh' />
        </form>you should see something like
    a ***Anne**** ***Albert**** b ***Anne**** ***Albert**** c ***Anne**** ***Albert****
      

  4.   

    谢谢您的回复,不过我实验后发现和我的程序运行结果一样,我看关键就是这句
    <cc:repeater id="childRepeater" runat="server" fId="Ringer">
    您是把fID使用了固定的值,如果换成父循环的值,就不会有子循环了,我如果这样写的话(我把数据源换成了我的数据库)
    <cc:repeater id="childRepeater" runat="server" fId='<%# DataBinder.Eval(Container.DataItem, "class_id") %>'>
    就不显示子循环,如果给父循环加上ItemDataBound就可以显示子循环
      

  5.   

    sorry, you are right, you need to override OnDataBinding instead,  try1. MySpace.cs:using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    using System.Data.SqlClient;
    using System.Data;namespace MySpace
    { [DefaultProperty("Text"), 
    ToolboxData("<{0}:repeater runat=server></{0}:repeater>")]
    public class repeater : System.Web.UI.WebControls.Repeater, INamingContainer
    {
    private string fId;

    [Bindable(true), 
    Category("Appearance"), 
    DefaultValue("")] 
    public string FId 
    {
    get
    {
    return fId;
    } set
    {
    fId = value;
    }
    }
         protected override void OnDataBinding(EventArgs e)
    {
          base.OnDataBinding(e);if (fId != null && fId.Length > 0)
    {
    //I modify the following for testing purpose
           SqlConnection cn = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=;");
           DataTable dt = new DataTable("authors");
    SqlCommand cmd = new SqlCommand("select * from authors where au_lname = @name", cn);
    cmd.Parameters.Add("@name", fId);
           SqlDataAdapter sda = new SqlDataAdapter(cmd);
           sda.Fill(dt);
          
          this.DataSource = dt;
    }      this.Controls.Clear();
          base.ClearChildViewState();
          this.CreateControlHierarchy(true);
          base.ChildControlsCreated = true;
    }
     
    }
    }2. TestSpace.aspx:<%@ Page Language="c#" %>
    <%@ Import Namespace="System.Data" %><%@ Register TagPrefix="cc" Assembly="MySpace" Namespace="MySpace" %><script runat="server">
    void Page_Load(object sender, EventArgs e)
    {
      if (!IsPostBack)
      {
       string[] s = {"White","Green","Smith"};
       Repeater1.DataSource = s;
       Repeater1.DataBind();
      }
    }   
    </script>    <form runat="server">
            <asp:repeater id="Repeater1" runat="server">

                <itemtemplate>
                   <%# Container.DataItem%>
                    <cc:repeater id="childRepeater" runat="server" fId='<%# Container.DataItem%>'>
                        <ItemTemplate>
                            ***<%# DataBinder.Eval(Container.DataItem, "au_fname") %>**** 
                        </ItemTemplate>
                    </cc:repeater>
                   
                </itemtemplate>
            </asp:repeater>
           <asp:Button id="btn" runat='server' Text='Refresh' />
        </form>
    3. output:
    White ***Johnson**** Green ***Marjorie**** Smith ***Meander****