0

In my webpage i use the following in order filling the listview control

<asp:ListView ID="ListView1" runat="server">
<layouttemplate>
<asp:PlaceHolder id="itemPlaceholder" runat="server" /></layouttemplate>
<ItemTemplate>
<tr>
            <td><asp:Label ID="Label1" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans1") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans1Visible") %>'></asp:Label>
                <br />
                <asp:Label ID="Label2" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans2") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans2Visible") %>'></asp:Label>
                <br />
                <asp:Label ID="Label3" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans3") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans3Visible") %>'></asp:Label>
                <br />
                <asp:Label ID="Label4" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans4") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans4Visible") %>'></asp:Label>
                <br />
                <asp:Label ID="Label5" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans5") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans5Visible") %>'></asp:Label>
                <br />
                <asp:Label ID="Label6" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans6") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans6Visible") %>'></asp:Label>
           </td>
        </tr>
</ItemTemplate>
</asp:ListView>

Now i would like to add numbers to the labels before they are rendered.

For example currently the data displayed are like

Tennis
Football
Basketball
Nfl
Nba
Polo

and the output i would like to have is

1. Tennis
2. Football
3. Basketball
4. Nfl
5. Nba
6. Polo

Could i use ListView1_ItemCreated or the ListView1_ItemDataBound event to achieve this? If that is true, could you point me a place to start?

P.S. the list view is filled with

Dt = GetDataTable("SELECT Ans1, Ans2,Ans3,Ans4,Ans5,Ans6, Ans1Visible,Ans2Visible,Ans3Visible,Ans4Visible,Ans5Visible,Ans6Visible, From myTable WHERE CatID ='" & cat & "'")
        ListView1.DataSource = Dt
        ListView1.DataBind()
OrElse
  • 9,709
  • 39
  • 140
  • 253
  • Does the content have to be rendered in a table? Using an ol (ordered list), rather than a table would allow the browser to automatically generate the numbers for you. I'd also be interested to know what your data structure looks like as it seems like you're using a ListView to represent a single row of data. – GShenanigan May 24 '10 at 16:24
  • Yeap, they have to be displayed in a table,(you see a simplified version here) – OrElse May 24 '10 at 16:30
  • So to clarify your data structure: You have a query which returns multiple records, each containing Ans1, Ans2, Ans3... and Ans1Visible, Ans2Visible... etc. You then have multiple table rows, each of which contains this list of 6 items? Just trying to get a clearer picture of the goal. – GShenanigan May 24 '10 at 16:41
  • Yeap all above are true. – OrElse May 24 '10 at 16:45
  • I'd recommend looking at how your have your database structured. It seems like it should be more normalized. What do you plan to do if the higher ups tell you they want a seventh answer added to the list view? You would have to update your DB, and make code changes. If you properly normalize you may be able to avoid both of those changes. I know this isn't the answer you're looking for but it may be the most important issue with your application right now... – Abe Miessler May 24 '10 at 17:49
  • Also it appears that there might be a SQL Injection vulnerability based on the code you posted that uses the GetDataTable function. – Abe Miessler May 24 '10 at 17:50

4 Answers4

2
    <asp:ListView ID="ListView1" runat="server">
    <layouttemplate>
    <asp:PlaceHolder id="itemPlaceholder" runat="server" /></layouttemplate>
    <ItemTemplate>
    <ol>

<asp:Literal ID="Label1" runat="server" Text = '<%# Eval("Ans1","<li>{0}</li>") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans1Visible") %>'></asp:Label>

 <asp:Literal ID="Label2" runat="server" Text = '<%# Eval( "Ans2","<li>{0}</li>") %>' Visible = '<%# Eval(Container.DataItem, "Ans2Visible") %>'></asp:Label>

<asp:Literal ID="Label3" runat="server" Text = '<%# DataBinder.Eval("Ans3","<li>{0}</li>") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans3Visible") %>'></asp:Label>

 <asp:Label ID="Label4" runat="server" Text = '<%# Eval("Ans4","<li>{0}</li>) %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans4Visible") %>'></asp:Label>
</ol>
    </ItemTemplate>
    </asp:ListView>

You are better off using OL (Ordered List).Then you generate the list elements as part of the Eval format string. If you hardcode your numbers they may display incorrectly when items are not visible(visible=false). You can change the style of display of li using CSS

josephj1989
  • 9,509
  • 9
  • 48
  • 70
1

An alternative to the example above would be to concat using ROW_NUMBER() in the SQL Select statement with the Ans field.

websch01ar
  • 2,103
  • 2
  • 13
  • 22
1

I think that josephj1989 is on the correct path, but is missing the table row code that you stated in your comments was required.

The complete solution would be something like this:

<asp:ListView ID="ListView1" runat="server">
  <LayoutTemplate>
    <asp:PlaceHolder id="itemPlaceholder" runat="server" />
  </LayoutTemplate>
  <ItemTemplate>
    <tr>
      <td>
        <ol>
          <asp:Literal ID="Literal1" runat="server" Text = '<%# Eval("Ans1","<li>{0}</li>") %>' Visible = '<%# Eval("Ans1Visible") %>' />
          <asp:Literal ID="Literal2" runat="server" Text = '<%# Eval("Ans2","<li>{0}</li>") %>' Visible = '<%# Eval("Ans2Visible") %>' />
          <asp:Literal ID="Literal3" runat="server" Text = '<%# Eval("Ans3","<li>{0}</li>") %>' Visible = '<%# Eval("Ans3Visible") %>' />
          <asp:Literal ID="Literal4" runat="server" Text = '<%# Eval("Ans4","<li>{0}</li>) %>' Visible = '<%# Eval("Ans4Visible") %>' />
        </ol>
      </td>
    </tr>
  </ItemTemplate>
</asp:ListView>

If you are wanting to use the OnItemDataBound approach, the following event handler would work for you:

protected void lvData_OnItemDataBound(object sender, ListViewItemEventArgs e)
{
    int count = 1;

    foreach (Literal lit in e.Item.Controls.OfType<Literal>())
    {
        if (lit.Visible)
        {
            lit.Text = String.Format("{0}. {1}", count.ToString(), lit.Text);
            count++;
        }
    }
}
sgriffinusa
  • 4,203
  • 1
  • 25
  • 26
0

Based on your code and what you want displayed it seems like the itemCreated and ItemDataBound events will only be fired once which would mean (to me at least) that they wouldn't be a great place to add these numbers (unless it will be 1-6 everytime).

Are you sure you fully understand how the ListView should be used? What are you using as your datasource for this ListView?

If you are sure you have everything setup the way you would like you could just hardcode 1-6 into the markup:

<tr>
            <td>1:<asp:Label ID="Label1" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans1") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans1Visible") %>'></asp:Label>
                <br />
                2:<asp:Label ID="Label2" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans2") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans2Visible") %>'></asp:Label>
                <br />
                3:<asp:Label ID="Label3" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans3") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans3Visible") %>'></asp:Label>
                <br />
                4:<asp:Label ID="Label4" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans4") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans4Visible") %>'></asp:Label>
                <br />
                5:<asp:Label ID="Label5" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans5") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans5Visible") %>'></asp:Label>
                <br />
                6:<asp:Label ID="Label6" runat="server" Text = '<%# DataBinder.Eval(Container.DataItem, "Ans6") %>' Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans6Visible") %>'></asp:Label>
           </td>
        </tr>
Abe Miessler
  • 82,532
  • 99
  • 305
  • 486
  • The itemCreated and ItemDataBound are not fired once, since they are filled by database – OrElse May 24 '10 at 16:28
  • Based on your output they are being fired only once unless you are making every label in a record invisible with this line: Visible = '<%# DataBinder.Eval(Container.DataItem, "Ans1Visible") %>'. Is that what is going on? – Abe Miessler May 24 '10 at 16:31
  • Also if this data is coming from a database it might help to see the structure of the underlying tables. I suspect that you may have some normalization issues which could be causing this to be over complicated. – Abe Miessler May 24 '10 at 16:32
  • The data source of the list view is an SQL query. I cannot hard-code the 1-6 since some queries return 2 rows for each ItemTemplate and some other 3, 4, 5 or 6 – OrElse May 24 '10 at 16:48