0

I would like to create a very simple image gallery. I am trying to figure out how to bind a Repeater to some kind of a custom object that would return back a list of files and/or folders. Can somebody point me in the right direction?

UPDATE: Here's what i have so far, please let me know if there's a better way to do this

ListView to display my folders

<asp:ListView ID="lvAlbums" runat="server" DataSourceID="odsDirectories">
    <asp:ObjectDataSource ID="odsDirectories" runat="server" SelectMethod="getDirectories" TypeName="FolderClass">
       <SelectParameters>
          <asp:QueryStringParameter DefaultValue="" Name="album" QueryStringField="album" Type="String" />
       </SelectParameters>
    </asp:ObjectDataSource>

ListView to display my thumbnails

<asp:ListView ID="lvThumbs" runat="server" DataSourceID="odsFiles">
<asp:ObjectDataSource ID="odsFiles" runat="server" SelectMethod="getFiles" TypeName="FolderClass">
   <SelectParameters>
      <asp:QueryStringParameter Type="String" DefaultValue="" Name="album" QueryStringField="album" />
   </SelectParameters>
</asp:ObjectDataSource>

And here's FolderClass

public class FolderClass
{
   private DataSet dsFolder = new DataSet("ds1");

   public static FileInfo[] getFiles(string album)
   {
      return new DirectoryInfo(System.Web.HttpContext.Current.Server.MapPath("/albums/" + album)).GetFiles();

   }
   public static DirectoryInfo[] getDirectories(string album)
   {
      return new DirectoryInfo(System.Web.HttpContext.Current.Server.MapPath("/albums/" + album)).GetDirectories()
                .Where(subDir => (subDir.Name) != "thumbs").ToArray();

   }
}
PBG
  • 8,944
  • 7
  • 34
  • 48

2 Answers2

1

You can bind a repeater to any list. In your case a list DirectoryInfo's may be relevant, or if you want files AND folders, some sort of custom object that holds both:

class FileSystemObject
{
    public bool IsDirectory;
    public string Name;
}

...

List<FileSystemObject> fsos = ...; // populate this in some fashion

repFoo.DataSource = fsos;
repFoo.DataBind();
Noon Silk
  • 54,084
  • 6
  • 88
  • 105
  • You put me on the right track, but can i can do this without creating a class? Here's what i got so far public class FolderClass { private DataSet dsFolder = new DataSet("ds1"); public FolderClass(string path){} public static FileInfo[] getFiles() {return new DirectoryInfo(@"E:\Documents\Projects\aaa.com\albums\Bridal Bqt").GetFiles();} } – PBG Aug 28 '09 at 00:17
  • Not if you need to handle Directories AND files. Also, maybe update your main post, it's a bit hard to read code in this little comment section :) Also, the way you have written it, it is quite nicely encapsulated, so I wouldn't worry about it. Nicely done. – Noon Silk Aug 28 '09 at 00:19
0

You can use .NET Anonymous Types and LINQ like the code below from ClipFlair (http://clipflair.codeplex.com) Gallery metadata input page (assumes a using System.Linq clause):

private string path = HttpContext.Current.Server.MapPath("~/activity");

protected void Page_Load(object sender, EventArgs e)
{
  if (!IsPostBack) //only at page 1st load
  {
    listItems.DataSource =
      Directory.EnumerateFiles(path, "*.clipflair")
               .Select(f => new { Filename=Path.GetFileName(f) });
    listItems.DataBind(); //must call this
  }
}

The above snippet gets all *.clipflair files from ~/activity folder of your web project

Update: using EnumerateFiles (availabe since .NET 4.0) instead of GetFiles since this is more efficient with LINQ queries. GetFiles would return a whole array of filenames in memory before LINQ had a chance to filter it.

The following snippet shows how to use multiple filters (based on answer at Can you call Directory.GetFiles() with multiple filters?), which GetFiles/EnumerateFiles don’t support themselves:

private string path = HttpContext.Current.Server.MapPath("~/image");
private string filter = "*.png|*.jpg";

protected void Page_Load(object sender, EventArgs e)
{
  _listItems = listItems; 

  if (!IsPostBack)
  {
    listItems.DataSource =
      filter.Split('|').SelectMany(
        oneFilter => Directory.EnumerateFiles(path, oneFilter)
                     .Select(f => new { Filename = Path.GetFileName(f) })
      );

    listItems.DataBind(); //must call this

    if (Request.QueryString["item"] != null)
      listItems.SelectedValue = Request.QueryString["item"];
                          //must do after listItems.DataBind
  }
}

The snippet below shows how to get all directories from /~video folder and also filters them to select only directories that contain a .ism file (Smooth Streaming content) with the same name as the directory (e.g. someVideo/someVideo.ism)

private string path = HttpContext.Current.Server.MapPath("~/video");

protected void Page_Load(object sender, EventArgs e)
{ 
  if (!IsPostBack) //only at page 1st load
  {
    listItems.DataSource = 
      Directory.GetDirectories(path)
        .Where(f => (Directory.EnumerateFiles(f, Path.GetFileName(f) + ".ism").Count() != 0))
        .Select(f => new { Foldername = Path.GetFileName(f) });
    //when having a full path to a directory don't use Path.GetDirectoryName (gives parent directory),
    //use Path.GetFileName instead to extract the name of the directory

    listItems.DataBind(); //must call this
  }
}

The examples above are from a DropDownList, but it's the same logic with any ASP.net control that supports Data Binding (note I'm calling Foldername the data field at the 2nd snippet and Filename at the first one, but could use any name, need to set that in the markup):

  <asp:DropDownList ID="listItems" runat="server" AutoPostBack="True" 
    DataTextField="Foldername" DataValueField="Foldername" 
    OnSelectedIndexChanged="listItems_SelectedIndexChanged"
    />
Community
  • 1
  • 1
George Birbilis
  • 2,782
  • 2
  • 33
  • 35