2013-04-10 3 views
1

Мне нужно отобразить результаты двух отдельных запросов как бок о бок столбцов в одной и той же таблице html. Каждый из двух наборов данных поступает из хранимой процедуры через SqlDataSource ASP.NET, и каждый из них возвращает одинаковое количество строк. Я хотел бы выход выглядеть следующим образом:Использование репитеров для генерации столбцов в таблице HTML

<table> 
    <tr> 
    <td>Row 1 from Stored Procedure 1</td> 
    <td>Row 1 from Stored Procedure 2</td> 
    </tr> 
    <tr> 
    <td>Row 2 from Stored Procedure 1</td> 
    <td>Row 2 from Stored Procedure 2</td> 
    </tr> 
    ... 
    <tr> 
    <td>Row n from Stored Procedure 1</td> 
    <td>Row n from Stored Procedure 2</td> 
    </tr> 
</table> 

Можно ли сделать это в пределах одного элемента управления Repeater ASP, используя «альтернативную строку» функциональность? Возможно ли выполнить два репитера ASP рядом друг с другом? Есть ли другой контроль, который может это сделать?

+0

Поскольку я не мог найти решение, которое мне понравилось, я положил два повторителя рядом друг с другом, а затем использовал CSS, чтобы придать им вид одной таблицы. – dneaster3

ответ

1

Я не думаю, что это возможно со столом.

Вы могли бы сделать что-то вроде этого:

<div style="width:500px;float:left;"> 
    <asp:Repeater ID="Repeater1"> 
     <div style="width:100%;height:25px;"><asp:Label ID="RowDataLabel"></asp:Label></div> 
    </asp:Repeater> 
</div> 
<div style="width:500px;float:left;"> 
    <asp:Repeater ID="Repeater2"> 
     <div style="width:100%;height:25px;"><asp:Label ID="RowDataLabel"></asp:Label></div> 
    </asp:Repeater> 
</div> 

(я знаю, что я не хватает какой-то код)

Как это фактически визуализирует будет зависеть от того, насколько и как аналогичные данные в каждой строке является .. один очень длинный бит данных может сбросить весь макет. Вы также можете использовать <ul> вместо <div>, если у вас есть проблемы с css.

Другим вариантом является получение двух наборов данных в коде, использование LINQ для их объединения, а затем визуализация единого комбинированного набора данных в сетку или ретранслятор.

+0

Я согласен с вашим первоначальным предложением, это не представляется возможным, используя только повторители. – dneaster3

+0

@ dneaster3: Пожалуйста, взгляните на мой ответ, в котором используются повторители. Это соответствует вашим потребностям? –

0

У вас есть колонка, где вы можете присоединиться к ним? Если да, то вы могли бы сделать, это соединить таблицы в на DataSet с DataRelation а в странице вы можете получить Чайлдс или родителя, используя эти отношения, следуя примеру

код позади:

protected void Page_Load(object sender, EventArgs e) 
{ 
    DataSet ds1 = new DataSet(); 
    DataSet ds2 = new DataSet(); 

    DataTable dt1 = new DataTable("Table1"); 
    DataTable dt2 = new DataTable("Table2"); 

    DataSet ds = new DataSet("DataSet"); 

    dt1.Columns.Add("Eno", typeof(Int32)); 
    dt1.Columns.Add("Ename", typeof(String)); 
    dt1.Columns.Add("Salary", typeof(Double)); 
    dt1.Columns.Add("Deptno", typeof(Int32)); 
    dt1.PrimaryKey = new DataColumn[] { dt1.Columns["Eno"] }; 

    dt2.Columns.Add("Deptno", typeof(Int32)); 
    dt2.Columns.Add("Dname", typeof(String)); 
    dt2.PrimaryKey = new DataColumn[] { dt2.Columns["Deptno"] }; 

    ds1.Tables.Add(dt1); 
    ds2.Tables.Add(dt2); 

    // Loading data into dt1, dt2: 

    object[] o1 = { 1, "dvs.kiran kumar", 50000.50, 10 }; 
    object[] o2 = { 2, "Raj", 4000.50, 20 }; 
    object[] o3 = { 3, "Gary", 10000.50, 30 }; 

    object[] c1 = { 10, "MFG" }; 
    object[] c2 = { 20, "EAS" }; 
    object[] c3 = { 30, "E&U" }; 
    object[] c4 = { 40, "PES" }; 

    dt2.Rows.Add(c1); 
    dt2.Rows.Add(c2); 
    dt2.Rows.Add(c3); 
    dt2.Rows.Add(c4); 

    dt1.Rows.Add(o1); 
    dt1.Rows.Add(o2); 
    dt1.Rows.Add(o3); 

    DataSet dsJoined = new DataSet(); 
    dsJoined.Tables.Add(ds1.Tables[0].Copy()); 
    dsJoined.Tables.Add(ds2.Tables[0].Copy()); 
    DataRelation drel = new DataRelation("EquiJoin", dsJoined.Tables[1].Columns["Deptno"], dsJoined.Tables[0].Columns["Deptno"]); 
    dsJoined.Relations.Add(drel); 

    rptJoined.DataSource = dsJoined.Tables[1]; 
    rptJoined.DataBind(); 


} 

разметка:

 <asp:Repeater runat="server" ID="rptJoined"> 
     <HeaderTemplate> 
      <table> 
     </HeaderTemplate> 
     <ItemTemplate> 

      <tr> 
       <td> 
      Depto: <%# ((System.Data.DataRowView) Container.DataItem)["Dname"] %> 
       </td> 
      <asp:Repeater runat="server" ID="rptChild" DataSource='<%# ((System.Data.DataRowView) Container.DataItem).Row.GetChildRows("EquiJoin") %>'> 
       <ItemTemplate> 
        <td> 
       Ename: <%# ((System.Data.DataRow) Container.DataItem)["Ename"] %> 
        </td> 
       </ItemTemplate> 
      </asp:Repeater> 
      <tr> 

     </ItemTemplate> 
     <FooterTemplate> 
      </table> 
     </FooterTemplate> 
    </asp:Repeater> 

Другим вариантом является использование события OnItemDataBound от ретранслятора и получить значение в коде позади.

код позади:

protected void rptJoined_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
    { 

     DataRowView drv = (DataRowView)e.Item.DataItem; 

     Literal ltrColumn1 = (Literal)e.Item.FindControl("ltrColumn1"); 
     Literal ltrColumn2 = (Literal)e.Item.FindControl("ltrColumn2"); 

     ltrColumn1.Text = drv["Dname"].ToString(); 

     var childs = drv.Row.GetChildRows("EquiJoin"); 

     if (childs.Count() > 0) 
     { 
      ltrColumn2.Text = childs[0]["Ename"].ToString(); 
     } 
    } 
} 

разметка:

<asp:Repeater runat="server" ID="rptJoined" OnItemDataBound="rptJoined_ItemDataBound"> 
     <HeaderTemplate> 
      <table> 
     </HeaderTemplate> 
     <ItemTemplate> 
      <tr> 
       <td> 
        <asp:Literal runat="server" ID="ltrColumn1" /> 
       </td> 
       <td> 
        <asp:Literal runat="server" ID="ltrColumn2" /> 
       </td> 
      <tr> 
     </ItemTemplate> 
     <FooterTemplate> 
      </table> 
     </FooterTemplate> 
    </asp:Repeater> 

Приветствие

+0

В ответ на ваш первый вопрос нет, две таблицы не могут быть объединены, или я бы сделал это с помощью хранимой процедуры для одного повторителя. – dneaster3

+0

Я впечатлен уровнем усилий и подробностей в вашем ответе, но я бы не решался включить ретранслятор внутри другого ретранслятора. Для этого требуется либо (a), чтобы таблица данных для вложенного ретранслятора была создана асинхронно, как это было в случае с методом событий Page_Load, или (б) событие данных (запрос, хранимая процедура и т. Д.), Чтобы произойти _each time_ внешняя строка databinds один из его строк. – dneaster3

1

Поскольку оба DataTables имеют одинаковое число строк, вы можете установить первую таблицу в качестве источника данных и доступ к значения из второй таблицы с использованием e.Item.ItemIndex.

Так что это будет ваша Repeater разметка:

<asp:Repeater ID="rptData" runat="server" OnItemDataBound="rptData_ItemDataBound"> 
    <HeaderTemplate> 
     <table border="1" > 
    </HeaderTemplate> 
    <ItemTemplate> 
     <tr> 
      <td><asp:Label ID="lblFirst" runat="server" /></td> 
      <td><asp:Label ID="lblSecond" runat="server" /></td> 
     </tr> 
    </ItemTemplate> 
    <FooterTemplate> 
     </table> 
    </FooterTemplate> 
</asp:Repeater> 

А вы бы обрабатывать OnItemDataBound так:

protected void rptData_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
    { 
     ((Label)e.Item.FindControl("lblFirst")).Text = ((DataRowView)e.Item.DataItem)["Value"].ToString(); 
     ((Label)e.Item.FindControl("lblSecond")).Text = this.dtSecond.Rows[e.Item.ItemIndex]["Value"].ToString(); 
    } 
} 

Вот остальная часть кода-за так у вас есть полный рабочий образец:

//PAGE-LEVEL VARIABLES 
DataTable dtFirst = new DataTable(); 
DataTable dtSecond = new DataTable(); 

protected void Page_Load(object sender, EventArgs e) 
{ 
    this.PopulateDatasources(); 
    this.rptData.DataSource = this.dtFirst; 
    this.rptData.DataBind(); 
} 

private void PopulateDatasources() 
{ 
    DataRow row = null; 
    dtFirst.Columns.Add(new DataColumn("Value")); 
    dtSecond.Columns.Add(new DataColumn("Value")); 
    row = dtFirst.NewRow(); 
    row["Value"] = "First - 01"; 
    dtFirst.Rows.Add(row); 
    row = dtFirst.NewRow(); 
    row["Value"] = "First - 02"; 
    dtFirst.Rows.Add(row); 
    row = dtSecond.NewRow(); 
    row["Value"] = "Second - 01"; 
    dtSecond.Rows.Add(row); 
    row = dtSecond.NewRow(); 
    row["Value"] = "Second - 02"; 
    dtSecond.Rows.Add(row); 
} 

Дайте мне знать, если это сработает для вас.

+0

У вас была возможность попробовать это? –

+0

Мне нравится это решение для простоты и удобочитаемости. Я не поклонник того, что вы называете «переменными уровня страницы», но в этом случае имеет смысл, почему вы их использовали. – dneaster3

+0

Просто интересно, почему вы не являетесь поклонником переменных «page-level»? –

Смежные вопросы