2013年11月22日星期五

listview中分列展示数据

listview控件就像windows资源管理器右边的内容视图,有大图标、小图标、列表、平铺、详细信息几种展示方式,我这次做的需要看目录下的文件夹和文件以及更新时间,另外再加个文件类型和大小,所以就使用详细信息的方式,具体做法如下:
1 在listview的属性窗口的View属性选择Details
2 Colomns属性中,添加需要的几列,并将Text改成要展示的列名字
3 代码中添加方法
[csharp] view plaincopy
  1. //获取文件夹和文件列表  
  2. public void GetDirectorysAndFiles(int index)  
  3. {  
  4.     string path = datatable_folders.Rows[index]["Folder"].ToString();  
  5.     string protocol = datatable_folders.Rows[index]["Protocol"].ToString();  
  6.     string username = datatable_folders.Rows[index]["Username"].ToString();  
  7.     string password = datatable_folders.Rows[index]["Password"].ToString();  
  8.     if (protocol == "local")  
  9.     {  
  10.         DirectoryInfo dirs = new DirectoryInfo(path);  
  11.         foreach (DirectoryInfo dir in dirs.GetDirectories())  
  12.         {  
  13.             ListViewItem item = new ListViewItem();  
  14.             item.Text = dir.Name;  
  15.             //item.ImageIndex =   
  16.             item.SubItems.Add(dir.LastWriteTime.ToString("yyyy-MM-dd HH:mm"));  
  17.             item.SubItems.Add("文件夹");  
  18.             item.SubItems.Add("");  
  19.             listView1.Items.Add(item);  
  20.         }  
  21.         foreach (FileInfo file in dirs.GetFiles())  
  22.         {  
  23.             ListViewItem item = new ListViewItem();  
  24.             item.Text = file.Name;  
  25.             item.SubItems.Add(file.LastWriteTime.ToString("yyyy-MM-dd HH:mm"));  
  26.             item.SubItems.Add(file.Extension);  
  27.             item.SubItems.Add(file.Length.ToString());  
  28.             listView1.Items.Add(item);  
  29.         }  
  30.     }  
  31. }  
4 在对应的事件调用此方法,我的是鼠标双击listbox中的某个Item
[csharp] view plaincopy
  1. //listbox双击事件  
  2. private void listBox_folders_MouseDoubleClick(object sender, MouseEventArgs e)  
  3. {  
  4.     int index = listBox_folders.IndexFromPoint(e.Location);  
  5.     if (index != System.Windows.Forms.ListBox.NoMatches)  
  6.     {  
  7.         GetDirectorysAndFiles(index);  
  8.     }  
  9. }  

listview的第一列可以展示图片加文字,像文件夹和文件的图标,这个可以通过文件的后缀名去注册表中取对应的图标,具体比较麻烦,我暂时先不做了,对我无关紧要的。后面的每列都是SubItem,使用SubItems.Add方法添加,注意顺序对应就好了。

2013年11月20日星期三

从文本文件中的表读取到二维数组与DataTable并在listbox中展示其中的一列



自己做的一个winform小工具中,有一个listbox,我想在每次程序启动时从本地一个文件中读出数据,将其中的一列展示在listbox中,而且数据要保存在内存中,供之后的功能调用。查论坛说filestream方式读取文件比较好,而且可以每次只读一行,对于很大的文件也可以轻松应付,虽然我的文件不可能那么大,但是为了练习也采用了这种办法。filestream中的ReadLine()方法也可以得出文件的行数,以下是源代码:
[csharp] view plaincopy
  1. StreamReader streamreader = new StreamReader(FileOperation.folderfile);  
  2. string line;  
  3. while ((line = streamreader.ReadLine()) != null)  
  4. {  
  5.     string[] readrow = line.Split(new char[] { '\t' });  
  6.     int m = 1;  
  7.     int n = readrow.Length;  
  8.     string[,] fields = new string[m, n];  
  9.     for (int i = 0; i < n; i++)  
  10.         fields[i / n, i % n] = readrow[i];  
  11.     listBox_folders.Items.Add(fields[m-1, 0]);  
  12.     m++;  
  13. }  
具体的办法是通过循环将文件的每行都读出存入一个一维数组,再用一个for循环将这个一维数组的数据存入一个二维数组的一行,二维数组的列数由一维数组的长度取得,行数则随着ReadLine()的循环自增,最后listbox展示的是这个二维数组的第1列。

补:
随后的操作过程中,需要多次对该数组进行增删改操作,发现数组的操作很麻烦,于是只好重新来过,将数组改为DataTable类型,DataTable获取行数列数,索引,增删改操作都相当便利,而且我也熟悉,代码如下:
[csharp] view plaincopy
  1. StreamReader streamreader = new StreamReader(FileOperation.folderfile);  
  2. string line;  
  3. DataTable dt_folders = new DataTable();  
  4. DataColumn name = new DataColumn("Name", Type.GetType("System.String"));  
  5. DataColumn folder = new DataColumn("Folder", Type.GetType("System.String"));  
  6. DataColumn username = new DataColumn("UserName", Type.GetType("System.String"));  
  7. DataColumn password = new DataColumn("Password", Type.GetType("System.String"));  
  8. DataColumn protocol = new DataColumn("Protocol", Type.GetType("System.String"));  
  9. DataColumn port = new DataColumn("Port", Type.GetType("System.String"));  
  10. dt_folders.Columns.Add(name);  
  11. dt_folders.Columns.Add(folder);  
  12. dt_folders.Columns.Add(username);  
  13. dt_folders.Columns.Add(password);  
  14. dt_folders.Columns.Add(protocol);  
  15. dt_folders.Columns.Add(port);  
  16. DataRow row;  
  17. while ((line = streamreader.ReadLine()) != null)  
  18. {  
  19.     row = dt_folders.NewRow();  
  20.     string[] readrow = line.Split(new char[] { '\t' });  
  21.     row["Name"] = readrow[0].ToString();  
  22.     row["Folder"] = readrow[1].ToString();  
  23.     row["UserName"] = readrow[2].ToString();  
  24.     row["Password"] = readrow[3].ToString();  
  25.     row["Protocol"] = readrow[4].ToString();  
  26.     row["Port"] = readrow[5].ToString();  
  27.     dt_folders.Rows.Add(row);  
  28.     listBox_folders.Items.Add(row["Name"]);  
  29. }  
  30. datatable_folders = dt_folders.Copy();  
最后是复制给一个全局变量供全局使用。