views:

1016

answers:

4

I am fairly new to ASP.NET and I discovered repeaters recently. Some people use them, other don't and I'm not sure which solution would be the best practice.

From what I've experienced, it makes simple operation (display a list) simple, but as soon as you want to do more complicated things the complexity explodes, logic wise.

Maybe it's just me and me poor understanding of the concept (this is highly possible), so here's an example of what am I trying to do and my issue:


Problem: I want to display a list of files located in a folder.

Solution:

String fileDirectory = Server.MapPath("/public/uploaded_files/");
String[] files = Directory.GetFiles(fileDirectory);
repFiles.DataSource = files;
repFiles.DataBind();

and

<asp:Repeater ID="repFiles" runat="server" OnItemCommand="repFiles_ItemCommand" >
        <ItemTemplate>
           <a href="/public/uploaded_files/<%# System.IO.Path.GetFileName((string)Container.DataItem) %>" target="_blank">View in a new window</a> 
           <br />
        </ItemTemplate>  
</asp:Repeater>

This works fine.


New problem: I want to be able to delete those files.

Solution: I add a delete link in the item template:

<asp:LinkButton ID="lbFileDelete" runat="server" Text="delete" CommandName="delete" />

I catch the event:

   protected void repFiles_ItemCommand(object source, RepeaterCommandEventArgs e)
        {
            if (e.CommandName == "delete")
            {
                // ... blah
            }
        }

... then what? How do I get the file path that I want to remove from here knowing that e.Item.DataItem is null (I ran the debugger).

Did I just wasted my time using repeaters when I could have done the same thing using an loop, which would have been just as simple, just -maybe- less elegant?

What is the real advantage of using repeaters over other solutions?

+7  A: 

You can definitely handle the LinkButton events as you are showing. You can add a CommandArgument to your LinkButton like this:

<asp:LinkButton CommandArgument="<%# (string)Container.DataItem %>" ID="lbFileDelete" runat="server" Text="delete" CommandName="delete" />

Then in your code you can do this:

string path = e.CommandArgument.ToString();

In general, I'm a fan of the Repeater control. It gives you the ability to make repeating things quickly, with limited code and a high level of control over the generated HTML. I prefer it over the GridView and other more complex controls because you have much more fine-tuned ability to generate the output exactly as you need.

I prefer it over looping, because I believe you can develop faster, with fewer errors if you're not appending tons of HTML together in your code to make the generated HTML.

JerSchneid
ditto that... the control over the generated HTML is a huge benefit of the Repeater.
JasonS
but you also have control when you do something like - foreach thing in things <%="some HTML"%> - . You have even more control actually.
marcgg
@jerSchneid, I tried your solution and the page supposed to display the list goes : Parser ErrorDescription: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.Parser Error Message: The server tag is not well formed.
marcgg
The error is at: <asp:LinkButton CommandArgument="<%# Eval("Path") %>" ID="lbFileDelete" runat="server" Text="delete" CommandName="delete" />
marcgg
I think that has to do with the double quotes around "Path" inside the double quotes for CommandArgument. The Eval("Path") isn't what you want anyway... I edited the link button code above. Try it now.
JerSchneid
Awesome, it's working now ! thanks
marcgg
+2  A: 

For displaying a list of things, Repeaters are typically faster than GridViews, DataLists, and their other counterparts. Repeaters are best suited for display, rather than adding and editing records, although you can manually wire up what is needed to use a Repeater for CRUD operations.

In your example, you need to bind the file path to the CommandArgument property of your link button. Then you should have access to the path using e.CommandArgument in the event handler.

JasonS
+1  A: 

Repeaters are faster and more flexible than similar options because Repeaters do not add their own code. To some extent, they're a glorified for loop, though I think it's probably nicer to use a repeater since it keeps all your html code in the same place.

Brian
A: 

Repeaters rock. Especially repeaters of user controls that wrap up this sort of functionality.

Anyhow, the CommandArgument trick works very well, especially if you only need one argument. Another trick is to wire things to a separate handler (NOT the ItemCommand handler) and then use the sender to walk back into the item and pick up other data. ie:

<asp:LinkButton CommandArgument="<%# (string)Container.DataItem %>" ID="lbFileDelete" runat="server" Text="delete" OnClick="DeleteFile" />
<asp:Hidden runat="server" id="FileId" value="<%# DataBinder.Eval(Container.DataItem, "ID") %>

And then in the codebehind:

protected void DeleteFile(object sender, EventArgs e)
{
   LinkButton clicked = (LinkButton)sender;
   Control container = clicked.NamingContainer;
   int id = int.Parse(((Hidden)container.FindControl("FileId")).Value);
   //do stuff with the id, etc.
}

Pretty handy in more complex scenarios. Frankly I've never found much of anything in ASP.NET one can't do with a repeater and a bit of ingenuity.

Wyatt Barnett