JB11
JB11

Reputation: 53

How to pass multiple variables to a repeater using string lists

I've been looking for a way to use my repeater with multiple variables such as Creation date, file path, and parent folder, I was able to data bind to a string list to be able to populate the file path and I have a method that will put text into the labels but it only repeats the first item in the list for all label fields. Is there a way to pass multiple variables to the repeater for each of these fields?

.aspx

<asp:Repeater id="repLinks" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
   <ItemTemplate>
         <tr>
             <td>
      <asp:HyperLink runat="server" NavigateUrl='<%# Container.DataItem.ToString() %>' Text="<%# Container.DataItem.ToString().Split('\\').Last() %>"  />    
                 </td>
                  <td> 
      <asp:Label ID="CRD" runat="server" Text="Label"></asp:Label>           
                  </td>  
             <td>
      <asp:Label ID="USR" runat="server" Text="Label"></asp:Label>        
             </td>
                 </tr>      
            </ItemTemplate>
           </asp:Repeater> 

.aspx.cs

 public List<string> CD = new List<string>();
    public List<string> lLinks = new List<string>();
    public List<string> folder = new List<string>();
    public string root = "";
    protected void Page_Load(object sender, EventArgs e)
    {

        if (!IsPostBack)
        {
            //Welcomes User
            string Uname = Environment.UserName;
            UserName.Font.Size = 17;
            UserName.Text = "Welcome: " + Uname;
            Get_Vars();

            //Define your list contents here 
            repLinks.DataSource = lLinks;
            repLinks.DataBind();
        }

    }

    protected void Get_Vars()
    {
        //gives path and constructs lists for directory paths and file links
        root = "C:\\Users\\James\\Documents\\Visual Studio 2015\\WebSites";

        //adds files to list
        foreach (var path in Directory.GetDirectories(@root))
        {
            foreach (var path2 in Directory.GetFiles(path))
            {
                lLinks.Add(path2);
                CD.Add(File.GetCreationTime(path2).ToString());
                //CD.Add(File.GetCreationTime(path2).Date.ToString("yyyy-mm-dd"));
                string[] temp = Path.GetDirectoryName(path2).Split(new string[] { "\\" }, StringSplitOptions.None);
                folder.Add(temp[temp.Length-1]);
            }


        }
    }


    protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {

        foreach (RepeaterItem item in repLinks.Items)
        {
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                for(int k=0;k<CD.Count;k++) {
                    var lbl = (Label)item.FindControl("CRD");
                    //int k = 0;
                    lbl.Text = CD[k];    
                }
            }
            if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem)
            {
                var lbl = (Label)item.FindControl("USR");
                int k = 0;
                lbl.Text = folder[k];
                k++;
            }
        }
    }

Upvotes: 0

Views: 1382

Answers (2)

mason
mason

Reputation: 32694

Remove your ItemDataBound event handler. You don't need that just to bind some text to a label. It's better to do that declaratively.

You should encapsulate the data in a model.

public class CD
{
    public string Name {get; set;}
    public string Link {get; set;
    public string Folder {get; set;}
    //additional properties about the CD here
}

Then create a list of these, and bind that to your repeater.

List<CD> cds = new List<CD>();
//populate your list with data. Here's manually populating with one
CD cd = new CD
{
    Name = "Dark Side of the Moon",
    Link = "http://www.google.com/pinkfloyd",
    Folder = "C:\\Users\\etc"
};
cds.Add(cd);

repLinks.DataSource = cds;
repLinks.DataBind();

Lastly, strongly type your repeater and then you can access the properties.

<asp:Repeater id="repLinks" runat="server" ItemType="CD" OnItemDataBound="Repeater1_ItemDataBound">
    <!-- omit some stuff -->
    <%#: Item.Name %>  

Upvotes: 1

David
David

Reputation: 218847

Don't store related values in unrelated variables. Create an object which represents any given element in your repeater. Something like this:

public class MyObject
{
    public string CD { get; set; }
    public string Link { get; set; }
    public string Folder { get; set; }
}

Use a list of that object as your data source:

public List<MyObject> MyObjects = new List<MyObject>();

And populate that list with your data:

foreach (var path2 in Directory.GetFiles(path))
{
    string[] temp = Path.GetDirectoryName(path2).Split(new string[] { "\\" }, StringSplitOptions.None);

    MyObjects.Add(new MyObject {
        CD = File.GetCreationTime(path2).ToString(),
        Link = path2,
        Folder = temp[temp.Length-1]
    });
}

Bind to the list:

repLinks.DataSource = MyObjects;
repLinks.DataBind();

And in the repeater you can bind to the object's properties:

<%# ((MyObject)Container.DataItem).CD %>

or

<%# ((MyObject)Container.DataItem).Link %>

etc.

Whenever you have a logical grouping of data elements, group them. It becomes a whole lot easier to maintain than trying to keep a bunch of separate variables synchronized.

Upvotes: 1

Related Questions