您的位置:首页 > 编程语言 > ASP

海洋工作室——网站建设专家:How To: Create an ASP.NET AJAX Style Folder Explorer

2009-09-09 11:14 766 查看
Here is the original link,
http://mattberseth.com/blog/2007/07/hwo_to_create_an_aspnet_ajax_s.html
I recently created a folder explorer using a combination of the ASP.NET TreeView and GridView controls as well as the new ASP.NET AJAX UpdatePanel. You can view a live demo of the folder explorer here. The code for this sample is at the bottom of the page.

[Update 7/24/2007]: Here is another post regarding this, except with a few more enhancements

[Update 7/17/2007]: Per Ruckus' comments, I would like to make the following clarifications:

The sample provides read-only access to the folders and files, making it more of a 'Folder Browser' instead of an Explorer
A full-postback is done when a folder is clicked in the right hand pane. If you have a suggestion to a nice way to have the Folder image buttons cause async-postbacks instead of complete post-backs, let me know. I thought about possibly handling the RowDataBound event and explicitly calling RegisterAsyncPostBackControl ...
Offically the TreeView control is not supposed to work inside an UpdatePanel. I didn't run into any problem, but this is why I classified this post under 'prototype'. It needs a little more work/investigation.





The design of the page is pretty simple. The left panel is a regular ASP.NET TreeView that displays the folders I am allowing the users to browse. The right panel contains the selected folders contents - both files and folders. Both of these controls are contained within an UpdatePanel so traversing the folder structure does not cause the complete page to refresh.

Here is the markup for the TreeView (left panel):

<asp:TreeView ID="tvFolders" runat="server" OnSelectedNodeChanged="TvFolders_SelectedNodeChanged">
<NodeStyle ImageUrl="Img/folder.gif" HorizontalPadding="3px" Font-Underline="false" ForeColor="black" />
<SelectedNodeStyle Font-Underline="true" Font-Bold="true" />
</asp:TreeView>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

And here is the GridView (right panel). The only interesting part about the GridView is that because the GridView does not display Headers when the DataSource is empty, I am using the work a round outlined here.

<mb:GridView
ID="gvFolderItems" runat="server"
EmptyDataText="This folder is empty."
GridLines="None" Width="100%" BorderStyle="None"
OnRowDataBound="GvFolderItems_RowDataBound"
OnRowCommand="GvFolderItems_RowCommand"
AutoGenerateColumns="false" ShowHeaderWhenEmpty="true">
<HeaderStyle HorizontalAlign="Left" BackColor="BurlyWood" />
<Columns>
<asp:TemplateField HeaderText="Name">
<ItemTemplate>
<%--The image is set when row is databound--%>
<asp:ImageButton
ID="btnItemIcon" runat="server"
ImageAlign="AbsMiddle"
CommandArgument='<%# Eval("Name") %>'
CommandName="ItemClick" />
<asp:LinkButton
ID="btnItemName" runat="server"
Text='<%# Eval("Name") %>'
CommandArgument='<%# Eval("Name") %>'
CommandName="ItemClick"
Font-Underline="false"
ForeColor="black" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Size">
<ItemTemplate>
<%--The image is set when row is databound--%>
<asp:Label ID="lblSize" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</mb:GridView>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Finally, because I need use the Response object to write the PDF contents to the output stream, I have to notify the UpdatePanel that any postback that originates from the GridView needs to be a full postback (instead of an partial one - you can not write to the Response object during a partial-postback. If you do it will generate an error). This is done by adding the PostBackTrigger item to the UpdatePanels Triggers collection and point it to our GridView.

<Triggers>
<asp:AsyncPostBackTrigger ControlID="tvFolders" EventName="SelectedNodeChanged" />
<asp:PostBackTrigger ControlID="gvFolderItems" />
</Triggers>

The path to the physical folder structure I am allowing the user to browse is located at the 'rootfolder' appsetting key. Additionally, these folders only contain PDF files so when the directory item is a file I am always displaying the PDF icon. This logic is contained in the RowDataBound event handler and you will need to update it for each type of file your application supports. I am binding directly to the FileSystemInfo object and displaying the Name property value for both Folders and Files and the Size property for just the Files. You should be able to include other attributes in a similar manner.

That's It. Enjoy!

* Disclaimer: Offically the TreeView control is not supposed to work inside an UpdatePanel. I didn't run into any problem, but this is why I classified this posting under 'prototype'. It needs a little more work/investigation.

<%@ Page Language="C#" %>
<%@ Register Assembly="MattBerseth.WebControls" Namespace="MattBerseth.WebControls" TagPrefix="mb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<script runat="server">
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
string rootFolder = this.Server.MapPath(ConfigurationManager.AppSettings["rootfolder"]);

// load the treeview based on the folder strucutre
TreeNode rootNode = new TreeNode("Root", rootFolder);
rootNode.Expanded = true;
rootNode.Select();
// add the root node
this.tvFolders.Nodes.Add(rootNode);

// bind sub directories to the treeview
BindDirs(rootFolder, rootNode);

// bind the gridview to the datasource using the root node
BindDirsContents(rootNode, this.gvFolderItems);
}
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
protected void GvFolderItems_RowDataBound(object sender, GridViewRowEventArgs args)
{
if (args.Row.RowType == DataControlRowType.DataRow)
{
System.IO.FileSystemInfo item = (System.IO.FileSystemInfo)args.Row.DataItem;
ImageButton imageButton = (ImageButton)args.Row.FindControl("btnItemIcon");

if (item is System.IO.DirectoryInfo)
{
imageButton.ImageUrl = @"Img/folder.gif";
}
else
{
imageButton.ImageUrl = @"Img/pdf.gif";

System.IO.FileInfo fileInfo = (System.IO.FileInfo)item;
Label lblSize = (Label)args.Row.FindControl("lblSize");
lblSize.Text = string.Format("{0:N0} KB", fileInfo.Length / 1000);
}
}
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
protected void GvFolderItems_RowCommand(object sender, GridViewCommandEventArgs args)
{
// handle either opening the item or rebinding the grid
if (args.CommandName == "ItemClick")
{
string name = (string)args.CommandArgument;
System.IO.DirectoryInfo dinfo = new System.IO.DirectoryInfo(this.tvFolders.SelectedNode.Value);

if (System.IO.File.Exists(System.IO.Path.Combine(dinfo.FullName, name)))
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(System.IO.Path.Combine(dinfo.FullName, name));
// they clicked on a file, download it
// to there PC
this.Response.Clear();
this.Response.AddHeader("Content-Disposition", "attachment; filename=" + fileInfo.Name);
this.Response.AddHeader("Content-Length", fileInfo.Length.ToString());
this.Response.ContentType = "application/octet-stream";
this.Response.WriteFile(fileInfo.FullName);
this.Response.End();
}
else
{
foreach (TreeNode node in this.tvFolders.SelectedNode.ChildNodes)
{
if (node.Text == name)
{
node.Selected = true;
node.Expanded = true;

// expand the parents
TreeNode parentNode = node.Parent;
while (parentNode != null)
{
parentNode.Expanded = true;
parentNode = parentNode.Parent;
}

// bind the gridview to the datasource
BindDirsContents(node, this.gvFolderItems);
break;
}
}
}
}
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
protected void TvFolders_SelectedNodeChanged(object sender, EventArgs args)
{
BindDirsContents(this.tvFolders.SelectedNode, this.gvFolderItems);
}

/// <summary>
///
/// </summary>
/// <param name="node"></param>
private static void BindDirsContents(TreeNode node, System.Web.UI.WebControls.GridView gridView)
{
// bind the gridview to the datasource
gridView.DataSource = new System.IO.DirectoryInfo(node.Value).GetFileSystemInfos();
gridView.DataBind();
}

/// <summary>
///
/// </summary>
/// <param name="path"></param>
/// <param name="treeNode"></param>
private static void BindDirs(string path, TreeNode treeNode)
{
if (!string.IsNullOrEmpty(path))
{
foreach (string directoryPath in System.IO.Directory.GetDirectories(path))
{
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(directoryPath);
TreeNode subNode = new TreeNode(directory.Name, directory.FullName);
treeNode.ChildNodes.Add(subNode);

// bind sub directories
BindDirs(directoryPath, subNode);
}
}
}
</script>
</head>
<body>
<form id="form" runat="server">
<asp:ScriptManager ID="scriptManager" runat="server" />
<div>
<p style="background-color:AliceBlue; width:700px">
This is an example of how to combine a TreeView a GridView and an UpdatePanel to create a<br />
nice AJAX folder browser<br />
</p>
<br />
<asp:UpdatePanel ID="updPanel" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="tvFolders" EventName="SelectedNodeChanged" />
<asp:PostBackTrigger ControlID="gvFolderItems" />
</Triggers>
<ContentTemplate>
<table id="tbl" cellpadding="0px" cellspacing="0px">
<tr>
<td style="border:solid 1px black" valign="top">
<div style="overflow:auto;width:300px;height:450px;">
<asp:TreeView
ID="tvFolders" runat="server"
OnSelectedNodeChanged="TvFolders_SelectedNodeChanged">
<NodeStyle
ImageUrl="Img/folder.gif" HorizontalPadding="3px"
Font-Underline="false" ForeColor="black" />
<SelectedNodeStyle
Font-Underline="true" Font-Bold="true" />
</asp:TreeView>
</div>
</td>
<td style="border:solid 1px black" valign="top">
<div style="overflow:auto;width:400px;height:450px;">
<mb:GridView ID="gvFolderItems" runat="server" EmptyDataText="This folder is empty." GridLines="None" Width="100%" BorderStyle="None" OnRowDataBound="GvFolderItems_RowDataBound" OnRowCommand="GvFolderItems_RowCommand" AutoGenerateColumns="false" ShowHeaderWhenEmpty="true"> <HeaderStyle HorizontalAlign="Left" BackColor="BurlyWood" /> <Columns> <asp:TemplateField HeaderText="Name"> <ItemTemplate> <%--The image is set when row is databound--%> <asp:ImageButton ID="btnItemIcon" runat="server" ImageAlign="AbsMiddle" CommandArgument='<%# Eval("Name") %>' CommandName="ItemClick" /> <asp:LinkButton ID="btnItemName" runat="server" Text='<%# Eval("Name") %>' CommandArgument='<%# Eval("Name") %>' CommandName="ItemClick" Font-Underline="false" ForeColor="black" /> </ItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="Size"> <ItemTemplate> <%--The image is set when row is databound--%> <asp:Label ID="lblSize" runat="server" /> </ItemTemplate> </asp:TemplateField> </Columns> </mb:GridView>
</div>
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
<br />
</div>
</form>
</body>
</html>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐