我们实现一个简单的文件浏览器,这个示例没有通过手动循环文件或目录,而是利用 GridView 及数据绑定代码来处理所有的事情。
目录列表分别用了两个 GridView 控件创建,其中一个在另一个的上面。最上层的 GridView 显示目录,而底层的 GridView 显示文件。第二个 GridView 的ShowHeader 属性设为 false ,这样两个 GridView 就可以无缝地连接。
下面是提供目录列表的 GridView 控件声明,这个网格绑定到一个 DirectoryInfo 对象数组,显示 Name 以及 LastWriteTime 属性。它还创建 Size 列,不用于显示任何信息,只是保留空间以便目录列表与后面出现的文件列表较好地绑定在一块。此外,DirectoryInfo.FullName 属性被用作关键字段,这样用户单击目录时可以返回一个完整的路径。
<asp:GridView ID="gridDirList" runat="server" AutoGenerateColumns="false" OnSelectedIndexChanged="gridDirList_SelectedIndexChanged"
GridLines="None" CellPadding="0" CellSpacing="1" DataKeyNames="FullName">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img src="~/images/folder.jpg" alt="Folder" />
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField DataTextField="Name" CommandName="Select" HeaderText="Name" />
<asp:BoundField HeaderText="Size" />
<asp:BoundField DataField="LastWriteTime" HeaderText="LasT Modified" />
</Columns>
</asp:GridView>
然后是文件列表的 GridView ,必须定义一个 SelectedRowStyle,因为它要支持文件选择:
<asp:GridView ID="gridFileList" runat="server" AutoGenerateColumns="false" OnSelectedIndexChanged="gridFileList_SelectedIndexChanged"
GridLines="None" CellPadding="0" CellSpacing="1" DataKeyNames="FullName">
<SelectedRowStyle BackColor="#C0fFF" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<img src="~/images/file.jpg" alt="File" />
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField DataTextField="Name" CommandName="Select" />
<asp:BoundField DataField="Length" />
<asp:BoundField DataField="LastWriteTime" />
</Columns>
</asp:GridView>
下一步是编写代码来填充这些控件。其中的一个关键是 ShowDirectoryContents(),它读取当前文件夹的内容并绑定到两个 GridView 控件:
private void ShowDirectoryContents(string path)
{
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] files = dir.GetFiles();
DirectoryInfo[] dirs = dir.GetDirectories();
lblCurrentDir.Text = "Currently showing " + path;
gridFileList.DataSource = files;
gridDirList.DataSource = dirs;
Page.DataBind();
gridFileList.SelectedIndex = -1;
ViewState["CurrentPath"] = path;
}
页面首次加载时,调用这个方法来显示当前应用程序:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
ShowDirectoryContents(Server.MapPath("."));
}
}
ShowDirectoryContents()方法中用视图状态保存了当前显示的目录,这样就允许用户使用 Move Up 按钮浏览到当前目录的上一层:
protected void btnUp_Click(object sender, EventArgs e)
{
string path = ViewState["CurrentPath"].ToString();
path = Path.Combine(path,"..");
path = Path.GetFullPath(path);
ShowDirectoryContents(path);
}
要想在目录结构间移动,只需单击目录的链接即可,这会触发 SelectedIndexChanged 事件,接着事件处理程序显示出新目录:
protected void gridDirList_SelectedIndexChanged(object sender, EventArgs e)
{
string dir = gridDirList.DataKeys[gridDirList.SelectedIndex].Value.ToString();
ShowDirectoryContents(dir);
}
不过,如果用户从第二个 GridViw 里选择文件,会发生什么呢?此时,代码得到一个完整的文件路径,同时创建一个新的 FileInfo 对象并绑定到 FormView 控件,该控件通过一个模版显示文件的某些信息:
<asp:FormView ID="formFileDetails" runat="server">
<ItemTemplate>
<b>File:<%
1: # DataBinder.Eval(Container.DataItem,"FullName")
%></b><br />
Created at
<%
1: # DataBinder.Eval(Container.DataItem,"CreationTime")
%><br />
Last Updated at
<%
1: # DataBinder.Eval(Container.DataItem,"LastWriteTime")
%><br />
<i>
<%
1: # DataBinder.Eval(Container.DataItem,"Attributes")
%></i><br />
<%
1: # DataBinder.Eval(Container.DataItem,"Length")
%>
bytes.
<hr />
<%
1: # GetVersionInfoString(DataBinder.Eval(Container.DataItem,"FullName"))
%>
</ItemTemplate>
</asp:FormView>
protected void gridFileList_SelectedIndexChanged(object sender, EventArgs e)
{
string file = gridFileList.DataKeys[gridFileList.SelectedIndex].Value.ToString();
// 必须包装一下这个file 才能绑定到 FormView 控件上
ArrayList files = new ArrayList();
files.Add(new FileInfo(file));
formFileDetails.DataSource = files;
formFileDetails.DataBind();
}
protected string GetVersionInfoString(object path)
{
FileVersionInfo info = FileVersionInfo.GetVersionInfo(path.ToString());
return info.FileName + " " + info.FileVersion + "<br /> "
+ info.ProductName + " " + info.ProductVersion;
}
效果:
样式、效果、美化等工作这里就不再赘述了。