how can find every item INFO inside a repeater (in ItemCommand event) - repeater datasource is a List<> collection

4.9k views Asked by At

i have a list collection like below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace FileExplorer.Classes
  {
    public class NewAddedFiles
    {
        public string FileName { get; set; }
        public string FilePath { get; set; }
        public DateTime FileCreationDate { get; set; }
    }
}

    private void GetFilesFromDirectory(string PhysicalPath)
    {
        DirectoryInfo Dir = new DirectoryInfo(PhysicalPath);
        FileInfo[] FileList = Dir.GetFiles("*.*", SearchOption.AllDirectories);
        List<NewAddedFiles> list = new List<NewAddedFiles>();
        foreach (FileInfo FI in FileList)
        {
            NewAddedFiles NewAddedFile = new NewAddedFiles();
            string AbsoluteFilePath = FI.FullName;
            string RelativeFilePath =  string RelativeFilePath = "~/" + (AbsoluteFilePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty)).Replace("\\", "/");
            NewAddedFile.FileName = FI.Name;
            NewAddedFile.FilePath = RelativeFilePath;
            NewAddedFile.FileCreationDate = FI.CreationTime;
            list.Add(NewAddedFile);
        }
        Repeater1.DataSource = list;
        Repeater1.DataBind();
    }

my repeater in aspx is like below :

              <asp:Repeater ID="Repeater1" runat="server" 
                    onitemcommand="Repeater1_ItemCommand">
                    <ItemTemplate>
                        <asp:Image ID="imgArrowIconInsideRepeater" runat="server" ImageUrl="~/Images/Login/ArrowIcon.png" />
                        <asp:LinkButton ID="lbFile" runat="server" CommandName="lbFile_Click" CssClass="lbFileInRepeater"><%# Eval("FileName")%></asp:LinkButton>
                        <br />
                        <asp:Label ID="lblFileCreationDate" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "FileCreationDate", "{0:yyyy/MM/dd - tt h:m:s}") %>'
                            CssClass="lblFileCreationDateInRepeater"></asp:Label>
                        <div class="EmptyDiv">
                        </div>
                    </ItemTemplate>
                </asp:Repeater>

and Item_Command Of repeater in code behind :

protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{

    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        NewAddedFiles currentItem = (NewAddedFiles)e.Item.DataItem;

        switch (e.CommandName)
        {
            case "lbFile_Click":
                {
                    if (HttpContext.Current.Session["User_ID"] != null)
                    {
                        Response.Redirect("~/HandlerForRepeater.ashx?path=" + currentItem.FilePath);
                    }
                    else
                    {
                        ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('a');", true);
                    }
                    break;
                }

            default:
                {
                    break;
                }
        }
    }

}

my problem is currentItem is always null , when i click on every link button inside repeater!
i want to get FilePath of every link button inside repeater!
how can i do that ?

thanks in advance

4

There are 4 answers

1
jwheron On BEST ANSWER

From memory (and reinforced from Google searches), ItemCommand is one of the events that loads data from the ViewState. Once this happens, your original DataItem references do not exist anymore.

If you want to retrieve values from that item, as clunky as it sounds, you'll need to add a HiddenField to your Repeater ItemTemplate, like so:

<asp:HiddenField ID="filePath" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "FilePath")' />

and then replace this line:

Response.Redirect("~/HandlerForRepeater.ashx?path=" + currentItem.FilePath);

with these two lines:

HiddenField filePath = (HiddenField) e.Item.FindControl("filePath");
Response.Redirect("~/HandlerForRepeater.ashx?path=" + filePath.Value);
2
lampej On

I'm sure someone else will have a better answer than mine, but I can offer a workaround while you wait for that. You could add a hidden field that contains the FileName, and then use e.Item.FindControl("HiddenFieldFileName") to get at the value.

0
TheGeekYouNeed On

e.Item.DataItem is only available during the databinding event. You will need to use another method to extract the information you need. Put your primary key into a hidden field, retrieve that value, then

try something like

RepeaterItem ri = e.Item;
HiddenField pk = (HiddenField)ri.FindControl("pk");

int FileID = Convert.ToInt32(pk.Value);
// Create a NewAddedFiles object using the File's FileID (or whatever you have) and get the Filepath from that
0
JohnC On

In most cases there is no need for a hidden field, simply put the data value you need in the CommandArgument property of the button:

<asp:LinkButton ID="lbFile" runat="server" CommandName="lbFile_Click" CommandArgument='<%# Eval("FilePath")%>' CssClass="lbFileInRepeater"><%# Eval("FileName")%></asp:LinkButton>

Then in the ItemCommand() event retrieve the value:

string filePath = e.CommandArgument.ToString()

You may need to HTML encode the value assigned to CommandArgument so it won't break the HTML.

Suggest you don't set the CommandName value as if it is the name of an event handler method "lbFile_Click". Instead use a name to indicate the intended outcome or action, in this case "Navigate".