0

I am attempting to create dynamic li elements based on database values with output looking like :

<li id="myUniqueLiID" runat="server"><a href="vaiable url from db">variable string from db</a></li>

The amount of li elements will be determined at run time. I want to go with li elements because I think it leaves me with the most options for manipulation at a later time as oppose to several asp items I have worked with ie asp:ListBox.

Here is the code I am working with so far

SqlDatabase myconnection= new SqlDatabase(@"myconnection string");
DbCommand myproc= myconnection.GetStoredProcCommand("sp_MySP");

using (IDataReader LoadAllItems = myconnection.ExecuteReader(myproc))
{
    while (LoadAllItems.Read())
    {
         // retrieves ID from db
         int myID = LoadAllItems.GetInt32(0);
         // retrieves string from db
         string myName = LoadAllItems.GetString(1);
         // I have a static method that builds url based off id 
         // it takes an int and returns a string
         string restURL = MyLibrary.MyClass.StaticURLMethod(myID);

         //data bind to li element
         myLiID.datasource = LoadAllItems;
         //I think I build the li in datatextfield area but not 
         //sure if that is correct, or how to format.
         myLiID.datatextfield = ""; 
         myLiID.databind();
     }
}

If I am on the right track please a little guidance on where to go from here. If I am going off in the wrong direction please some guidance to the right path.

dan_vitch
  • 4,477
  • 12
  • 46
  • 69

2 Answers2

3

Here is a bit of guidance:

  • I'd separate between loading the data from the database, and binding it to a gui control. For example, first load it into a collection, and then bind that collection to a control.
  • "The amount of li elements will be determined at run time" - looks like you could use a Repeater to bind the data to. Make sure you create the li element in the repeater.

Let's say you create a method GetData which returns a Dictionary<int, string>, you could then bind that data to a Repeater.

The Repeater:

<asp:Repeater ID="rep" runat="server">
    <ItemTemplate>
        <li><a runat="server" id="myLink" /></li>
    </ItemTemplate>
</asp:Repeater>

Bind the data to the Repeater with something like this:

    private void BindData(Dictionary<int, string> dict){
        this.rep.ItemDataBound += new RepeaterItemEventHandler(rep_ItemDataBound);
        this.rep.DataSource = dict;
        this.rep.DataBind();   
    }

    void rep_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            KeyValuePair<int, string> kp = e.Item.DataItem as KeyValuePair<int, string>;
            //... find the control and update it with the correct values
        }
    }

I'll leave it to you to actually find the control and update it with the correct text and url.

Hope this helps in some way.

marapet
  • 54,856
  • 12
  • 170
  • 184
  • Repeaters are perfect for this sort of thing. – NotMe Jan 11 '11 at 23:48
  • 1
    thanks for the answer. It worked great. I am going to post an answer of my own on how to find the control and and update it, but I will mark yours as the answer since you gave me most of the info. – dan_vitch Jan 14 '11 at 21:23
  • Thx! You asked for a little guidance, so I thought you didn't want everything spelled out. Wasn't sure what to leave out... More on FindControl on SO: http://stackoverflow.com/questions/1203316/cant-find-control-within-asp-net-repeater – marapet Jan 14 '11 at 21:37
0

Here is the exact code I used after taking the recommendations from marapet:

 <div class="filterlist">
     <ul id="list">
         <asp:Repeater ID="MyList" runat="server">
              <ItemTemplate>
                  <li runat="server">
                     <asp:HyperLink ID="MyLink" runat="server" Text="" NavigateUrl=""/>
                  </li>
              </ItemTemplate>
         </asp:Repeater>
     </ul>
 </div>

This is the code behind

 protected void Page_Load(object sender, EventArgs e)
 {
 //This method return a dictionary with a URL, and a name
    if (!Page.IsPostBack)
        this.BindDate((Dictionary<string, string>)MyLibrary.Data.DataHelper.GetMytList());
 }

 private void BindDate(Dictionary<string, string> dict)
 {
    this.RestList.ItemDataBound += new RepeaterItemEventHandler(e_ItemDataBound);
    this.RestList.DataSource = dict;
    this.RestList.DataBind();
 }

 void e_ItemDataBound(object sender, RepeaterItemEventArgs e)
 {
    if ((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem))
    {
        KeyValuePair<string, string> mydict = (KeyValuePair<string, string>)e.Item.DataItem;
        HyperLink Link = (HyperLink)e.Item.FindControl("MyLink");
        Link.NavigateUrl = mydict.Value.ToString();
        Link.Text = mydict.Key.ToString();
    }
 }
dan_vitch
  • 4,477
  • 12
  • 46
  • 69