现有三个页面,一个为test.aspx,其余的分别是search.ascx和result.ascx
search.ascx是准备查询条件的,在点击查询后移除test.aspx页中的search.ascx用户控件并动态加载result.ascx控件,并在result.ascx的datagrid中显示结果集(可分页),以上都没问题,但在点击分页按钮时报错:未能加载视图状态。正在向其中加载视图状态的控件树必须与前一请求期间用于保存视图状态的控件树相匹配。例如,当以动态方式添加控件时,在回发期间添加的控件必须与在初始请求期间添加的控件的类型和位置相匹配。在线等待.
也可给其它可行方案,url传值就免了.因为查询的字段太多,有60多个.还有要有可重用性,因为查询和结果在多个页面中都要使用

解决方案 »

  1.   

    下面为一个例子,大家可以试试看,在点击分页按钮时会出错
    test.aspx
    <%@ Page Language="c#" Debug="False" Strict="True" Explicit="True" Buffer="True"%>
    <%@ Register TagPrefix="ms" TagName="search" src="~/search.ascx" %>
    <%@ Import Namespace="System" %>
    <html>
    <head>
    <title> New ASP.NET Document </title>
    </head>
    <body bgcolor="#FFFFFF" topmargin="0" marginheight="0"><script language="C#" runat="server">
      void Page_Load(Object Source, EventArgs E) {
      }
    </script>
    <form runat="server" method="">
    <asp:PlaceHolder id="plh" runat="server">
    <ms:search id="usrSearch" runat="server"/>
    </asp:PlaceHolder>
    </form>
    </body>
    </html>
    /////////
    search.ascx
    <%@ Control Language="c#" ClassName="search" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Web.UI.WebControls" %>
    <%@ Register TagPrefix="ms" TagName="result" Src="~/result.ascx" %>
    <script runat="server">
    void btnSearch_OnClick(object sender,System.EventArgs e){
    string str="Server=localhost;uid=sa;pwd=sz;initial catalog=Northwind";
    SqlConnection con=new SqlConnection(str);
    SqlDataAdapter da=new SqlDataAdapter("Select * from Employees",con);
    DataSet ds=new DataSet();
    da.Fill(ds);
    System.Web.UI.Page page=this.Parent.Page;
    PlaceHolder plh=(PlaceHolder)page.FindControl("plh");
    plh.Controls.Clear();
    result sr=(result)page.LoadControl("result.ascx");
    sr.DataSource=ds;
    plh.Controls.Add(sr);
    }
    </script>
    <asp:TextBox id="txt" runat="server"/>
    <asp:Button id="btnSearch" runat="server" Text="Search" OnClick="btnSearch_OnClick"/>
    ////////////
    result.ascx
    <%@ Control Language="C#" ClassName="result" %>
    <%@ Import Namespace="System" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Web.UI.WebControls" %>
    <script runat="server">
     public object DataSource{
    get{if(grid.DataSource!=null)
    return grid.DataSource;
    return null;}
    set{grid.DataSource=value;
        grid.DataBind();}
     } public void PageChanged(object sender,System.Web.UI.WebControls.DataGridPageChangedEventArgs e){
    grid.CurrentPageIndex=e.NewPageIndex;
     }
    </script>
    <asp:DataGrid id="grid" runat="server" BorderWidth="1px" width=480 height=200
    CellSpacing="1"  AutoGengrateColumns="true" AllowPaging="true" PageSize="3" OnPageIndexChanged="PageChanged"/>
      

  2.   

    To: LoveCherry
     
    统一接口?
    能不能详细一些,谢谢!!   
     
      

  3.   

    你是不是用 LoadControl 加载 ascx 的 ?
    可以把这些 代码移到  OnInit 事件中!
      

  4.   

    一般情况下,把 LoadControl 放在 用户事件中处理可以,
    但是你这种情况可以 要改一下业务逻辑,把  loadcontrol 放在 oninit 中处理!
      

  5.   

    To  rustical(时光流逝):
    你可以看看我上面的例子,没有办法移,因为是在点击search按钮后才加载result.ascx到test.aspx中的
      

  6.   

    用 viewstate 保存一个条件不可以吗?
    if  aa =1  then  loadcontrol(aa.ascx)
    if  aa =2  then  loadcontrol(bb.ascx) 
      

  7.   

    to rustical(时光流逝):
    不理解你说的,是在test.aspx页处理吗?因为现在我是在search.ascx处理加载页面的.问题是加载result.ascx页是可以的,但在result.ascx页上有事件发生的话,与test.aspx中的初始的视图状态不一致才出错的,可怎样在search.ascx中加载result.ascx后更新test.aspx页的视图状态,这是我的想法,但我不会,也不知道这个方法行不行,请赐教!
      

  8.   

    你可以试试用其他方法,
    用两张页面,search.aspx得到查询字符,传给第二张show.aspx的DataGrid显示,
    有时用户控件多也不一定是好事,传参量记的用session,因为特殊字符url不支持。
      

  9.   

    to nuoyiai(学已成舟):
    查询字段太多,用Session的话,如果分别保存,影响服务器.合并到一个Session中又要拆分字符,拆分后还要将每个参数传入存储过程.这简直是折磨人.还有没有其他的好办法
      

  10.   

    刚建了两个页面测试了一下,分页可行没出错。
    WebForm1.aspx
    如下
    先在页面上脱一个
    private void Page_Load(object sender, System.EventArgs e)
    {
    // 在此处放置用户代码以初始化页面
    if(myPlaceHolder.HasControls())
    {
    myPlaceHolder.Controls.Clear();
    }
    myPlaceHolder.Controls.Add(LoadControl("cccc.ascx"));
    }
    cccc.ascx如下
    private void Page_Load(object sender, System.EventArgs e)
    {
    // 在此处放置用户代码以初始化页面
    SqlDataAdapter myadapt=new SqlDataAdapter(sqlCommand1);
    DataSet DS=new DataSet();
    myadapt.Fill(DS);
    DataGrid1.DataSource=DS;
    DataGrid1.DataBind();}
    我都是拖的,省了些代码。你出错可能是没重新绑定好吧。我以前做的查询页,第一张是动态的,不管参数有多少,就一个动态生成的字符,查询参数太多也不好。
      

  11.   

    你的分页函数好像少了一次绑定
    public void PageChanged(object sender,System.Web.UI.WebControls.DataGridPageChangedEventArgs e){
    grid.CurrentPageIndex=e.NewPageIndex;
    /* 这里再对DataGrid绑定一次 */
     }
      

  12.   

    to  nuoyiai(学已成舟):
    是的,我没写,与这没问题.错误在test.aspx页执行LoadViewState时已出现.
      

  13.   

    在PostBack后,你需要在Page_Load里重新装载result.ascx,譬如test.aspx:<script language="C#" runat="server">
      void Page_Load(Object Source, EventArgs E) 
      {
         if (Page.IsPostBack && Session["ResultIn"] != null && (bool)Session["ResultIn"] == true)
         {
    Control sr= Page.LoadControl("result.ascx");
    plh.Controls.Add(sr);
         }
      }
    </script>
    search.ascx:
    void btnSearch_OnClick(object sender,System.EventArgs e){
    .....
    plh.Controls.Add(sr);
    Session["ResultIn"] = true;
    }
      

  14.   

    具體代碼我不寫了﹐講一下思路吧﹐
    你不能翻頁的原因是你的控件是動態加載的﹐所以每次加載時都會重新初始化狀態﹐我猜你在第一頁時是通過search.ascx把參數傳遞過來﹐所以能正常初始化﹐但翻頁后由于原來傳遞過來的參數都丟失﹐所以無法按預想的進行初始化。
    針對這種情況我的處理辦法是﹕在page里加一些屬性﹐當然這些屬性是用viewstat來記錄﹐每個屬性就對應一個字段﹐search時就把值傳到這些屬性里﹐result.ascx加載是就直接對這些屬性來取得參數﹐當然也可以建一個頁數的屬性
    好啦﹐具體代碼自己寫吧
      

  15.   

    http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpguide/html/cpconDevelopingUserControlsInCode-BehindFile.asp
      

  16.   

    To 思归老大:
    在点击分页时还是同样的错误。另外更正一下,Session要加在控件被清除之前。
    Session["ResultIn"] = true;
    plh.Controls.Clear();
    result sr=(result)page.LoadControl("result.ascx");
    sr.DataSource=ds;
    plh.Controls.Add(sr);
      

  17.   

    To liuzxit(如果):
    你指的是将所有的查询参数存到ViewState中吗,有6、70个之多,工作量太大。此外此法不通,因为错误在未加载result.ascx用户控件之前就已发生。难道用户控件真的不能解决出现的问题吗?
      

  18.   

    you have some problems with how the datasource is assigned, since I don't have your code, I will do some modificationstest.aspx:<%@ Page Language="c#" Debug="False" Strict="True" Explicit="True" Buffer="True" EnableSessionState="true"%>
    <%@ Register TagPrefix="ms" TagName="search" src="~/search.ascx" %>
    <%@ Import Namespace="System" %>
    <html>
    <head>
    <title> New ASP.NET Document </title>
    </head>
    <body bgcolor="#FFFFFF" topmargin="0" marginheight="0"><script language="C#" runat="server">
      protected override void LoadViewState(object state) 
      {
         if (!Page.IsPostBack)
    HttpContext.Current.Session["ResultIn"] = false;     if (Page.IsPostBack && Session["ResultIn"] != null && (bool)Session["ResultIn"] == true)
         {
    plh.Controls.Clear();
    Control sr= Page.LoadControl("result.ascx");
    sr.ID = "abc";
    plh.Controls.Add(sr); Response.Write("inside");
         }     base.LoadViewState(state);
      }
    </script>
    <form runat="server" method="">
    <asp:PlaceHolder id="plh" runat="server">
    <ms:search id="usrSearch" runat="server"/>
    </asp:PlaceHolder>
    <asp:BUtton text="refresh" runat="server" />
    </form>
    </body>
    </html>
    search.ascx
    <%@ Control Language="c#" ClassName="search" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Web.UI.WebControls" %>
    <%@ Register TagPrefix="ms" TagName="result" Src="~/result.ascx" %>
    <script runat="server">
    void btnSearch_OnClick(object sender,System.EventArgs e){System.Web.UI.Page page=this.Page;
    PlaceHolder plh=(PlaceHolder)page.FindControl("plh");
    plh.Controls.Clear();
    result sr=(result)page.LoadControl("result.ascx");
    if (sr != null)
    {
    sr.ID = "abc";
    plh.Controls.Add(sr);
    sr.BindData();
    HttpContext.Current.Session["ResultIn"] = true;
    }
    else
     Page.Response.Write("control is not loaded");
    }
    </script>
    <asp:TextBox id="txt" runat="server"/>
    <asp:Button id="btnSearch" runat="server" Text="Search" OnClick="btnSearch_OnClick"/>result.ascx
    <%@ Control Language="C#" ClassName="result" %>
    <%@ Import Namespace="System" %>
    <%@ Import Namespace="System.Data" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Web.UI.WebControls" %>
    <script runat="server">
     public object DataSource{
    get{if(grid.DataSource!=null)
    return grid.DataSource;
    return null;}
    set{grid.DataSource=value;
        grid.DataBind();}
     } public void BindData()
     {
    string str="Server=localhost;Integrated Security=SSPI;initial catalog=Northwind";
    SqlConnection con=new SqlConnection(str);
    SqlDataAdapter da=new SqlDataAdapter("Select * from Employees",con);
    DataSet ds=new DataSet();
    da.Fill(ds);
    grid.DataSource = ds.Tables[0].DefaultView;
    grid.DataBind();
     } public void PageChanged(object sender,System.Web.UI.WebControls.DataGridPageChangedEventArgs e){
    grid.CurrentPageIndex=e.NewPageIndex;
    //you need to set datgasource and call databind hereBindData();
    Page.Response.Write("inside result.ascx");
     }
    </script>result
    <asp:DataGrid id="grid" runat="server" BorderWidth="1px" width=480 height=200
    CellSpacing="1"  AutoGengrateColumns="true" AllowPaging="true" PageSize="3" OnPageIndexChanged="PageChanged"/>