2012-09-28 55 views
0

我有一個Repeater頁面,它遍歷一個自定義結構的List。 ItemTemplate具有附加到SqlDataSource的Repeater,該SqlDataSource非常簡單,並且將使用代碼隱藏中的結構信息來填充信息,其中WHERE子句的區別僅在於將<更改爲>。 StatementDate和AccountIndex是一個TextBox和DDL(分別),用戶填寫以定義信息。然而,所有試圖設置各種SqlDataSource的細節programmitcally導致沒有返回Repeater-in-Repeater的編程選擇SqlDataSource

<asp:Repeater ID="SelectedRepeater" runat="server" onitemdatabound="SelectedRepeater_ItemDataBound"> 
     <ItemTemplate> 
      <asp:Repeater ID="EntryRepeater" DataSourceID="RecordsDataSource" runat="server" OnItemDataBound="EntryRepeater_ItemDataBound"> 
       <ItemTemplate> 
        <tr> 
         <td> 
          <%# Eval("TrxDate", StandardDate) %> 
          <span class="error"><%# ShowExclamation(Eval("DateCleared")) %></span> 
         </td> 
         <td><%# Eval("Reference")%></td> 
         <td><%# Eval("VendorName")%></td> 
         <td><%# Eval("Memo")%></td> 
         <td class="money"><%# Eval("Amount","{0:n2}")%></td> 
        </tr> 
       </ItemTemplate> 
      </asp:Repeater> 
      <asp:SqlDataSource ConnectionString="<%=ConnectionString(ActiveClient)%>" ProviderName="System.Data.SqlClient" OnSelecting="RecordsDataSource_Selecting" ID="RecordsDataSource" OnDataBinding="RecordsDataSource_DataBinding" runat="server"> 
       <SelectParameters> 
        <asp:ControlParameter ControlID="StatementDate" DefaultValue="2/2/1900" Name="StatementDate" 
         PropertyName="Text" /> 
        <asp:ControlParameter ControlID="AccountIndex" DefaultValue="" Name="AccountIndex" 
         PropertyName="SelectedValue" /> 
       </SelectParameters> 
      </asp:SqlDataSource> 
     </ItemTemplate> 
    </asp:Repeater> 

我使用SqlDataSource控件的數據綁定和選擇和外Repeater的的ItemDataBound試圖(錯誤或行。):

protected void RecordsDataSource_DataBinding(object sender, EventArgs e) { 
    _currentCommand = String.Format(_standardSelect, Eval("WhereClause").ToString()); 
    SqlDataSource sds = sender as SqlDataSource; 
    sds.SelectCommandType = SqlDataSourceCommandType.Text; 
    sds.SelectCommand = String.Format(_standardSelect, Eval("WhereClause").ToString()); 
} 

protected void SelectedRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) { 
    if (IsListItemRow(e.Item)) { 
     SqlDataSource sds = (e.Item.FindControl("RecordsDataSource") as SqlDataSource); 
     sds.SelectCommand = String.Format(_standardSelect, ((PrintSection)e.Item.DataItem).WhereClause); 
     sds.Select(DataSourceSelectArguments.Empty); 
    } 
} 

protected void RecordsDataSource_Selecting(object sender, SqlDataSourceSelectingEventArgs e) { 
    e.Command.CommandText = _currentCommand; //set in DataBinding 
} 

(選擇命中四次,當我認爲它應該只有兩個,每個外部直放站項目一次)。

我將最終的CommandText與給定參數結合在一起,並在服務器管理器中獲得正確的結果,I甚至用一切硬編碼創建了一個新的SQLDataSource,並且工作得很好。雖然我可以使用硬編碼的sqlDataSources進行復制粘貼,但這會使編程失敗很多(儘管我現在已經完成了這個任務)。

我的想法是,這和頁面有關生命週期,但我不知道它會是什麼。在多次迭代中使用一個數據源是否可行?請注意,這僅用於選擇要顯示的數據,而不用於任何其他命令,因此我不需要擔心回發。 (我意識到這可以通過使用StoredProcedure來大大簡化;但是,所討論的數據庫是由另一個應用程序維護的,並且部署或確保在添加數據庫時部署SP是很煩人的,這是做這種事情的唯一頁面。)

回答

0

回答我自己的問題爲什麼不。

經過進一步測試證明我對頁面生命週期是正確的,但是出於錯誤的原因。我在Page_Init上做了外部Repeater的初始DataBinding;然後這會調用內部Repeater for DataBinding,但在生命週期中檢索用戶爲StatementDate和AccountIndex輸入的數據爲時尚早。將此更改爲Page_Load解決了該問題。

接下來,我決定假設爲多個RepeaterItems使用相同的SqlDataSource對象並且改變它不起作用(儘管我仍然不確定這一點),所以我轉而完全創建並綁定代碼隱藏中的SqlDataSource。最後,ASP代碼與問題中相同,減去SqlDataSource,代碼隱藏如下:

protected void SelectedRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) { 
    if (IsListItemRow(e.Item)) { //checks for both Item and AlternateItem 
     SqlDataSource sds = new SqlDataSource(ConnectionString(ActiveClient), 
       String.Format(_standardSelect, ((PrintSection)e.Item.DataItem).WhereClause)); 
     sds.SelectParameters.Add("StatementDate", StatementDate.Text); 
     sds.SelectParameters.Add("AccountIndex", AccountIndex.SelectedValue); 
     sds.Select(DataSourceSelectArguments.Empty); 
     Repeater innerRepeater = (e.Item.FindControl("EntryRepeater") as Repeater); 
     innerRepeater.DataSource = sds; 
     innerRepeater.DataBind(); 
    } 
}