自己练习用的代码写多了,想写一个页面可以方便的查看这些代码的运行效果。
要做导航肯定要用Treeview控件,还要得到文件夹和文件信息,查了下帮助,要使用DirectoryInfo类,MSDN的说明是:公开用于创建、移动和枚举目录和子目录的实例方法。无法继承此类。还要使用Request.PhysicalApplicationPath获得当前应用程序根目录的物理路径。解决了关键问题开始编写代码。
首先添加一个页面命名为LeftTree.aspx,拖进来一个TreeView控件,下面开始后台代码。
DirectoryInfo类在System.IO命名空间下,引入System.IO命名空间,
using System.IO;
在Page_Load事件里首先得到当前应用程序根目录的物理路径。
string physicalAppPath = Request.PhysicalApplicationPath;
然后实例化DirectoryInfo以便得到文件夹信息
DirectoryInfo dirInfo = new DirectoryInfo(physicalAppPath);
有了DirectoryInfo的实例就可以使用实例的GetFileSystemInfos()方法得到目录中所有文件和子目录,该方法返回FileSystemInfo型数组
FileSystemInfo[] fileSysInfos = directoryInfo.GetFileSystemInfos();
下面遍历SileSystemInfo数组将文件或文件夹的名称添加到TreeView控件。
首先在Page_Load之前定义节点
TreeNode node;
开始遍历
foreach (FileSystemInfo fileSysInfo in fileSysInfos)
{
node = new TreeNode();
node.Text = fileSysInfo.Name;
TreeView1.Nodes.Add(node);
}
这样就把根目录下所有文件和文件夹添加到了TreeView控件。
接下来要实现添加子文件下的文件了,这里需要一个递归。
private void GetFileAndDirectoryInfo(DirectoryInfo directoryInfo,TreeNode parentNode)
{
FileSystemInfo[] fileSysInfos = directoryInfo.GetFileSystemInfos();
foreach (FileSystemInfo fileSysInfo in fileSysInfos)
{
node = new TreeNode();
node.Text = fileSysInfo.Name;
parentNode.ChildNodes.Add(node);
}
}
当fileSysInfo的属性为Directory即文件夹时得到该文件夹下所有文件及子文件夹的信息,使用FileSystemInfo的Attributes属性
在上面的foreach里继续添加如下代码:
if (fileSysInfo.Attributes == FileAttributes.Directory)
{
//文件夹,递归调用GetFileAndDirectoryInfo()
DirectoryInfo dirinfo = new DirectoryInfo(fileSysInfo.FullName);
GetFileAndDirectoryInfo(dirinfo, node);
}
在Page_Load里调用该方法,此时Page_Load里的代码如下:
string physicalAppPath = Request.PhysicalApplicationPath;
DirectoryInfo dirInfo = new DirectoryInfo(physicalAppPath);
node = new TreeNode();
node.Text = dirInfo.Name;
TreeView1.Nodes.Add(node);
GetFileAndDirectoryInfo(dirInfo, node);
这样就可以以树状形式展示所有文件及文件夹了。但是我不想要cs文件等其他不方便在浏览器上显示的文件。接下来判断文件扩展名,不显示不想看到的文件。开始想使用枚举后来想用数组来定义要显示文件的扩展名信息,但是好像都不好判断一个字符串是否存在于一个枚举变量或字符串数组,干脆直接用字符串啦。
在Page_Load外定义变量:
string showExtensions = ".asp.aspx.htm.html.txt.xml."; //要显示的文件的扩展名
接下来在foreach的if语句后面添加else分支语句
else
{
//文件
if (showExtensions.IndexOf(fileSysInfo.Extension) > -1)
{
node = new TreeNode();
node.Text = fileSysInfo.Name;
parentNode.ChildNodes.Add(node);
}
}
这样if语句上面的三条添加节点的语句就需要拿到if里面来了。
这样就只得到了我想要的文件类型。
但是TreeView只有一个根节点,这样很难看,TreeView允许添加多个根节点,比如我们在显示产品类别的时候就会用到多个根节点。接下来就去掉这个根节点。
以前的做法是创建这个数的拷贝然后去掉根节……,反正感觉当时做的很麻烦,今天用如下方法实现。
给GetFileAndDirectoryInfo()方法添加一个参数,用来标示第二个参数也就是parentNode是否是根节点
private void GetFileAndDirectoryInfo(DirectoryInfo directoryInfo, TreeNode parentNode,bool isRoot)
用如下代码替换掉foreach里parentNode.ChildNodes.Add(node);
if (isRoot)
{
TreeView1.Nodes.Add(node);
}
else
{
parentNode.ChildNodes.Add(node);
}
这样去掉了难看的根节点。到此我们还没有给节点设置NavigateUrl属性,TreeView的节点在没有设置NavigateUrl属性或NavigateUrl值为空时默认产生一个SelectedNodeChange事件,我们为文件节点设置NavigateUrl属性,使得点击时打开我们的文件,设置文件夹节点的TreeNodeSelectAction属性为Expand,使得点击节点时展开或关闭节点而不产生SelectedNodeChange事件,在上面的if-else语句后添加如下代码:
if (fileSysInfo.Attributes == FileAttributes.Directory)
{
node.SelectAction = TreeNodeSelectAction.Expand;
}
else
{
node.NavigateUrl = node.ValuePath; //节点只有在添加之后才能得到ValuPath属性和Depth属性
}
下面添加一个框架页。2005却不支持框架,也不提供添加框架页,要是这样树节点还要个Target属性干什么啊。先添加一个Html页命名为Default.htm,用2003做一个框架页将代码拷贝过来,代码如下:
<frameset rows="*" border="0" frameSpacing="0" frameBorder="0">
<frameset cols="220,*">
<frame name="LeftTree" src="LeftTree.aspx">
<frame name="Main" src="Main.aspx">
</frameset>
<noframes>
</noframes>
</frameset>
在添加一个Main.aspx文件。然后在LeftTree.aspx.cs文件的node.NavigateUrl = node.ValuePath;代码后添加语句
node.Target = "Main";
这样就OK了。
完整代码附后。
我就做了这里了,接下来的问题是:当文件夹下没有可显示的文件时文件夹还会被添加到树中,很显然那是多余的,怎么样去掉呢?好像还得来一次递归。如果你有好办法可以一起来探讨。
第一次写这东东好像写的很罗嗦,请多批评指正,共同学习。
完整代码:
LeftTree.aspx:
<head runat="server">
<title>无标题页</title>
<style type="text/css">
body{ background-color:#d9eef5 }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TreeView ID="TreeView1" runat="server" Font-Size="12px" ForeColor="Black">
</asp:TreeView>
</div>
</form>
</body>
LeftTree.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
public partial class _LeftTree : System.Web.UI.Page
{
TreeNode node;
string showExtensions = ".asp.aspx.htm.html.webconfig.txt.xml.";
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//string mapPath = Server.MapPath("~"); //获得当前应用程序根目录的物理路径
string physicalAppPath = Request.PhysicalApplicationPath; //</div>
DirectoryInfo dirInfo = new DirectoryInfo(physicalAppPath);
node = new TreeNode();
node.Text = dirInfo.Name;
GetFileAndDirectoryInfo(dirInfo, node, true);
TreeView1.ShowLines = true;
TreeView1.Font.Size = FontUnit.Parse("12px");
TreeView1.CollapseAll();
}
}
void GetFileAndDirectoryInfo(DirectoryInfo directoryInfo, TreeNode parentNode,bool isRoot)
{
FileSystemInfo[] fileSysInfos = directoryInfo.GetFileSystemInfos();
foreach (FileSystemInfo fileSysInfo in fileSysInfos)
{
if (fileSysInfo.Attributes == FileAttributes.Directory)
{
//文件夹
AddNode(parentNode, isRoot, fileSysInfo);
DirectoryInfo dirinfo = new DirectoryInfo(fileSysInfo.FullName);
GetFileAndDirectoryInfo(dirinfo, node, false);
}
else
{
//文件
if (showExtensions.IndexOf(fileSysInfo.Extension) > -1)
{
AddNode(parentNode, isRoot, fileSysInfo);
}
}
}
}
private void AddNode(TreeNode parentNode, bool isRoot, FileSystemInfo fileSysInfo)
{
node = new TreeNode();
node.Text = fileSysInfo.Name;
if (isRoot)
{
TreeView1.Nodes.Add(node);
}
else
{
parentNode.ChildNodes.Add(node);
}
if (fileSysInfo.Attributes == FileAttributes.Directory)
{
node.SelectAction = TreeNodeSelectAction.Expand;
}
else
{
node.NavigateUrl = node.ValuePath; //节点只有在添加之后才能得到ValuPath属性和Depth属性
node.Target = "Main";
}
}
}
Default.html
<frameset rows="*" border="0" frameSpacing="0" frameBorder="0">
<frameset cols="220,*">
<frame name="LeftTree" src="LeftTree.aspx">
<frame name="Main" src="Main.aspx">
</frameset>
<noframes>
</noframes>
</frameset>