Asp.net 从codebehind访问listview项模板

Asp.net 从codebehind访问listview项模板,asp.net,vb.net,listview,itemtemplate,Asp.net,Vb.net,Listview,Itemtemplate,我希望动态更改ListView的ItemTemplate中的列数: <asp:ListView runat="server" ID="ReportListView" DataSourceID="ReportListViewSDS"> <LayoutTemplate> <table> <tr> <asp:PlaceHolder runat="server" ID="itemPlaceHolder" /

我希望动态更改ListView的ItemTemplate中的列数:

<asp:ListView runat="server" ID="ReportListView" DataSourceID="ReportListViewSDS">
 <LayoutTemplate>
   <table>
       <tr>
           <asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
       </tr>
   </table>
 </LayoutTemplate>
 <ItemTemplate>
       <!-- need to dynamically create the number of columns in the code behind 
            based on the select statement in the SelectCommand -->
 </ItemTemplate>
</asp:ListView>

然后在后面的代码中,我得到:

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    ' Based on The Request.Form variables sent, the SQL command will 
    ' select x number of columns:
    ' SqlStatement = "SELECT " for each Request.Form values " FROM staff"
    '      example: "SELECT Fname, Lname, email, phone FROM staff"
    ' Run sql command.

    ' that all works, the question now is how do i change the ItemTemplate 
    ' so that it has the correct number of columns.  Something like this: (pseudo code)
    For each row found in sql command
       ReportListView.ItemTemplate.Add( "<tr>" )
       For each Request.Form as i
            ReportLIstView.ItemTemplate.Add( "<td>" & sqlresult(i) & "</td>" )
       Next
       ReportListView.ItemTemplate.Add( "</tr>" )
    Next
 End Sub
Protected Sub Page_Load(ByVal sender作为对象,ByVal e作为System.EventArgs)处理Me.Load
'根据发送的请求.Form变量,SQL命令将
'选择x列数:
'SqlStatement=“SELECT”用于每个请求。表单值“来自员工”
'示例:“从员工处选择Fname、Lname、电子邮件和电话”
'运行sql命令。
'所有这些都有效,现在的问题是如何更改ItemTemplate
'以便它具有正确的列数。类似这样的内容:(伪代码)
对于sql命令中找到的每一行
ReportListView.ItemTemplate.Add(“”)
对于每个请求,请按我的要求填写表格
ReportLIstView.ItemTemplate.Add(“&sqlresult(i)&”)
下一个
ReportListView.ItemTemplate.Add(“”)
下一个
端接头

也许还有别的办法,但这是我们到目前为止唯一的想法。asp.net新手,有任何建议,非常欢迎!谢谢

我想你得稍微改变一下。试着这样做:

<table>
    <asp:ListView ID="ListView1" runat="server">
        <ItemTemplate>
            <tr>
               <asp:PlaceHolder Id="PlaceHolder1" runat="server" />
            </tr>
        </ItemTemplate>
    </asp:ListView>
</table>

语法可能并不完美,但请尝试在代码隐藏中执行以下操作:

For Each listItem As ListViewDataItem In ListView1.Items
    Dim plc As PlaceHolder = DirectCast(listItem.FindControl("PlaceHolder1"), PlaceHolder)
    If plc IsNot Nothing Then
        For Each item As String In Request.Form
            plc.Controls.Add(New Literal(String.Format("<td>{0}</td>", item)))
        Next
    End If
Next
将每个listItem作为ListView1.Items中的ListViewDataItem进行

Dim plc作为占位符=DirectCast(listItem.FindControl(“占位符1”),占位符)
如果plc不是什么,那么
在Request.Form中将每个项作为字符串
Add(新文本(String.Format(“{0}”,item)))
下一个
如果结束
下一个

另一种方法是以相同的方式设置ItemTemplate,但由于您使用的是数据绑定控件,因此可能需要利用listview的数据绑定事件。此语法可能并不完美,因为您可能正在使用不同的集合绑定到列表(这将在查询执行后完成),但这将使您走上正确的轨道:

Protected Sub ReportListView_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ReportListView.ItemDataBound
    If (e.Item.ItemType = ListViewItemType.DataItem) Then
        Dim di As Data.DataRowView = e.Item.DataItem
        Dim plc As PlaceHolder = DirectCast(e.Item.FindControl("PlaceHolder1"), PlaceHolder)

        For Each c In di.Row.ItemArray
            Dim l As New Literal
            l.Text = String.Format("<td>{0}</td>", c.ToString)
            plc.Controls.Add(l)
        Next

    End If
End Sub
Protected Sub ReportListView_ItemDataBound(ByVal sender作为对象,ByVal e作为System.Web.UI.WebControls.ListViewItemEventArgs)处理ReportListView.ItemDataBound
如果(e.Item.ItemType=ListViewItemType.DataItem),则
Dim di As Data.DataRowView=e.Item.DataItem
Dim plc作为占位符=DirectCast(例如Item.FindControl(“占位符1”),占位符)
对于di.Row.ItemArray中的每个c
Dim l作为新文本
l、 Text=String.Format(“{0}”,c.ToString)
plc.控制.添加(l)
下一个
如果结束
端接头

我通常会使用一个中继器来完成这类工作,因为它是轻量级的。从我看到的情况来看,您确实没有利用任何listview功能。

结合我收到的答案,这就是我要做的工作:

<asp:ListView runat="server" ID="ReportListView" DataSourceID="ReportListViewSDS">
 <ItemTemplate>
   <table>
       <tr>
           <asp:PlaceHolder runat="server" ID="itemPlaceHolder" />
       </tr>
   </table>
 </ItemTemplate>
</asp:ListView>

代码隐藏:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

 ' Based on The Request.Form variables sent, the SQL command will 
 ' select x number of columns:
 ' SqlStatement = "SELECT " for each Request.Form values " FROM staff"
 '      example: "SELECT Fname, Lname, email, phone FROM staff"
 ' Run sql command.

 ' this seems to actually run the sql, and bind the results.  If i don't run the function DataBind(), it's as if the sql never runs.
 ReportListView.DataBind() 

 ' the rest of the work is done in the next function.
End Sub

Protected Sub ReportListView_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewItemEventArgs) Handles ReportListView.ItemDataBound

    If (e.Item.ItemType = ListViewItemType.DataItem) Then
        Dim plc As PlaceHolder = DirectCast(e.Item.FindControl("itemPlaceHolder"), PlaceHolder)
        Dim di As Data.DataRowView = e.Item.DataItem()

        For Each c In di.Row.ItemArray
            Dim l As New Literal
            l.Text = String.Format("<td class='customreport'>{0}</td>", c.ToString)
            plc.Controls.Add(l)
        Next

    End If
End Sub
Protected Sub Page_Load(ByVal sender作为对象,ByVal e作为System.EventArgs)处理Me.Load
'根据发送的请求.Form变量,SQL命令将
'选择x列数:
'SqlStatement=“SELECT”用于每个请求。表单值“来自员工”
'示例:“从员工处选择Fname、Lname、电子邮件和电话”
'运行sql命令。
'这似乎实际运行了sql,并绑定了结果。如果我不运行函数DataBind(),就好像sql从未运行过一样。
ReportListView.DataBind()文件
'剩下的工作将在下一个函数中完成。
端接头
受保护的子ReportListView_ItemDataBound(ByVal sender作为对象,ByVal e作为System.Web.UI.WebControl.ListViewItemEventArgs)处理ReportListView.ItemDataBound
如果(e.Item.ItemType=ListViewItemType.DataItem),则
Dim plc作为占位符=DirectCast(例如Item.FindControl(“itemPlaceHolder”),占位符)
Dim di As Data.DataRowView=e.Item.DataItem()
对于di.Row.ItemArray中的每个c
Dim l作为新文本
l、 Text=String.Format(“{0}”,c.ToString)
plc.控制.添加(l)
下一个
如果结束
端接头

非常感谢其他两个答案的指导,这肯定让我得到了90%,只是一些其他的调整,我很乐意去做。谢谢

我使用此代码隐藏项模板中的元素

visible='<%# Eval("Abstract").ToString().Length == 0 ? false : true %>' 
visible=''

Great ideas,实现了它,但在这方面出现了一个错误:plc.Controls.Add(New Literal(String.Format(“{0}”,item)))。错误为“public sub new()的参数太多”。不熟悉Literal以及它在这里的使用方式,有什么建议吗?仅供参考:由于plc.Controls.Add takes和object,我尝试了以下方法:Dim tb As New TableCell()tb.Text=“Hello”plc.Controls.Add(tb),它不会给出任何错误,但似乎不会向listview的每一行添加“Hello”:(我成功了。必须添加ListView.DataBind()在for each循环之前。现在的问题是for each Item As String In Request.Form,我实际上需要它遍历从sql返回的每一列,因为我将把从sql命令返回的值放在plc.Control中。有什么想法吗?谢谢!这实际上就是使用ItemDataBound事件的意义。每次iew绑定一行数据,此事件将使用包含要绑定的数据行的事件参数激发。因此,您可以将另一个答案与此答案组合,并具有列标题和从每行检索的值。代码看起来很棒,已实现。出现错误:“对象引用未设置为对象的实例。”关于这一行:plc.Controls.Add(l)。玩了一点,asp.net似乎无法意识到“l”不是空对象。非常感谢您的帮助。顺便说一句,我使用listview是因为我希望能够对列表进行排序,而我对Repeater不熟悉。我将对此进行研究,谢谢!