使用ListView模仿Windows系统的资源管理器界面,实现文件(夹)的浏览、重命名、删除及查询等功能,主要功能界面展示如下:
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.IO; 10 11 namespace Controls 12 { 13 public partial class MainForm : Form 14 { 15 #region 成员变量 16 /// <summary> 17 /// 用于递归计算文件夹大小 18 /// </summary> 19 private long folderSize = 0; 20 21 /// <summary> 22 ///打开文件夹根路径 23 /// </summary> 24 private string rootPath = string.Empty; 25 #endregion 26 27 #region 初期化 28 /// <summary> 29 /// 默认构造函数 30 /// </summary> 31 public MainForm() 32 { 33 InitializeComponent(); 34 //给窗体注册键盘事件 35 this.KeyPreview = true; 36 } 37 38 /// <summary> 39 /// 初始化窗体,绑定事件 40 /// </summary> 41 /// <param name="sender"></param> 42 /// <param name="e"></param> 43 private void MainForm_Load(object sender, EventArgs e) 44 { 45 this.大图标ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click); 46 this.详细信息ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click); 47 this.平铺ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click); 48 this.小图标ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click); 49 this.列表ToolStripMenuItem.Click += new System.EventHandler(this.ToolStripMenuItem_Click); 50 } 51 #endregion 52 53 #region 事件处理 54 /// <summary> 55 /// 搜索框符合条件的人员 56 /// </summary> 57 /// <param name="sender"></param> 58 /// <param name="e"></param> 59 private void btnSearch_Click(object sender, EventArgs e) 60 { 61 AddItemsToListView(txtPath.Text, txtSearch.Text.Trim()); 62 AddHeaderToListView(this.lvwData); 63 } 64 65 /// <summary> 66 /// 给搜索框添加Enter快捷键 67 /// </summary> 68 /// <param name="sender"></param> 69 /// <param name="e"></param> 70 private void MainForm_KeyDown(object sender, KeyEventArgs e) 71 { 72 //搜索框获得焦点且按下Enter键时,执行搜索 73 if (txtSearch.Focused && e.KeyCode == Keys.Enter) 74 { 75 this.btnSearch_Click(sender, e); 76 } 77 } 78 79 /// <summary> 80 /// 返回上级目录 81 /// </summary> 82 /// <param name="sender"></param> 83 /// <param name="e"></param> 84 private void btnUp_Click(object sender, EventArgs e) 85 { 86 if (txtPath.Text == rootPath || !txtPath.Text.Contains("\\")) 87 { 88 return; 89 } 90 //找到文件夹上级目录的绝对路径 91 txtPath.Text = txtPath.Text.Substring(0, txtPath.Text.LastIndexOf("\\")); 92 AddItemsToListView(txtPath.Text); 93 AddHeaderToListView(this.lvwData); 94 } 95 96 /// <summary> 97 /// 打开文件夹,显示文件夹 98 /// </summary> 99 /// <param name="sender"></param> 100 /// <param name="e"></param> 101 private void btnFolder_Click(object sender, EventArgs e) 102 { 103 DialogResult dr = fbdData.ShowDialog(); 104 string path = fbdData.SelectedPath.ToString(); 105 if (dr == DialogResult.OK && path != "") 106 { 107 rootPath = path; 108 txtPath.Text = path; 109 } 110 } 111 112 /// <summary> 113 /// 新建文件夹,选中文件夹 114 /// </summary> 115 /// <param name="sender"></param> 116 /// <param name="e"></param> 117 private void btnAdd_Click(object sender, EventArgs e) 118 { 119 string fullpath = string.Empty; 120 AddForm addForm = new AddForm(btnAdd.Text); 121 addForm.ShowDialog(); 122 if (addForm.ButtonFlag) 123 { 124 fullpath = txtPath.Text + "\\" + addForm.TxtName; 125 } 126 else 127 { 128 return; //排除关闭窗口异常 129 } 130 try 131 { 132 if (Directory.Exists(fullpath)) 133 { 134 MessageBox.Show("该文件名已经存在!", "提示"); 135 return; 136 } 137 Directory.CreateDirectory(fullpath); 138 AddItemsToListView(txtPath.Text); 139 AddHeaderToListView(this.lvwData); 140 } 141 catch (NullReferenceException ex) 142 { 143 MessageBox.Show(ex.Message, "提示"); 144 } 145 finally 146 { 147 //选中新增的项,并显示在视野范围内 148 for (int i = 0; i < lvwData.Items.Count; i++) 149 { 150 if (lvwData.Items[i].Tag.ToString() == fullpath) 151 { 152 //先设置ListView选中 153 lvwData.Focus(); 154 lvwData.Items[i].Selected = true; 155 //在视野范围内显示 156 lvwData.EnsureVisible(i); 157 break; 158 } 159 } 160 } 161 } 162 163 /// <summary> 164 /// 重命名文件夹 165 /// </summary> 166 /// <param name="sender"></param> 167 /// <param name="e"></param> 168 private void btnRename_Click(object sender, EventArgs e) 169 { 170 if (lvwData.SelectedItems.Count <= 0) 171 { 172 return; 173 } 174 string fullName = lvwData.SelectedItems[0].Tag.ToString(); 175 string path = fullName.Substring(0, fullName.LastIndexOf("\\") + 1);//文件路径 176 string suffix = GetSuffixName(fullName);//后缀名 177 //文件名或文件夹名 178 string fileName = string.Empty; 179 if (suffix != string.Empty) 180 { 181 fileName = fullName.Substring(fullName.LastIndexOf("\\") + 1, 182 fullName.LastIndexOf(".") - fullName.LastIndexOf("\\") - 1);//文件名 183 } 184 else 185 { 186 fileName = fullName.Substring(fullName.LastIndexOf("\\") + 1);//文件夹名 187 } 188 string fullPath = string.Empty; 189 AddForm addForm = new AddForm(btnRename.Text, fileName); 190 addForm.ShowDialog(); 191 if (suffix != string.Empty) 192 { 193 fullPath = path + addForm.TxtName + "." + suffix; 194 } 195 else 196 { 197 fullPath = path + addForm.TxtName; 198 } 199 //直接关闭窗口时 200 if (!addForm.ButtonFlag) 201 { 202 return; 203 } 204 try 205 { 206 //重命名文件夹 207 if (suffix == string.Empty) 208 { 209 if (Directory.Exists(fullPath)) 210 { 211 MessageBox.Show("该文件名已经存在!", "提示"); 212 return; 213 } 214 Directory.Move(fullName, fullPath); 215 } 216 //重命名文件 217 else 218 { 219 if (File.Exists(fullPath)) 220 { 221 MessageBox.Show("该文件名已经存在!", "提示"); 222 return; 223 } 224 File.Move(fullName, fullPath); 225 } 226 AddItemsToListView(txtPath.Text); 227 AddHeaderToListView(this.lvwData); 228 } 229 catch (NullReferenceException ex) 230 { 231 MessageBox.Show(ex.Message); 232 } 233 } 234 235 /// <summary> 236 /// 删除文件夹 237 /// </summary> 238 /// <param name="sender"></param> 239 /// <param name="e"></param> 240 private void btnDelete_Click(object sender, EventArgs e) 241 { 242 int count = lvwData.SelectedItems.Count; 243 if (count <= 0) 244 { 245 return; 246 } 247 DialogResult result = MessageBox.Show("你确定删除这" + count + "项吗?", "提示", 248 MessageBoxButtons.YesNo, MessageBoxIcon.Question); 249 if (result == DialogResult.Yes) 250 { 251 string path; 252 ListViewItem selectitem; 253 for (int i = 0; i < lvwData.SelectedItems.Count; ) //此处不能i++ 254 { 255 selectitem = lvwData.SelectedItems[i]; 256 path = selectitem.Tag.ToString(); 257 lvwData.Items.Remove(selectitem); 258 if (File.Exists(path)) 259 { 260 File.Delete(path); 261 } 262 else if (Directory.Exists(path)) 263 { 264 Directory.Delete(path, true); 265 } 266 lvwData.Update(); 267 } 268 } 269 } 270 271 /// <summary> 272 /// List选中项时发生 273 /// </summary> 274 /// <param name="sender"></param> 275 /// <param name="e"></param> 276 private void lvwData_ItemActivate(object sender, EventArgs e) 277 { 278 ListView lv = (ListView)sender; 279 if (lv.SelectedItems.Count <= 0) 280 { 281 return; 282 } 283 string filename = lv.SelectedItems[0].Tag.ToString(); 284 //如果是文件夹,就打开它 285 if (Directory.Exists(filename)) 286 { 287 AddItemsToListView(filename); 288 AddHeaderToListView(this.lvwData); 289 //获取打开的文件夹路径 290 txtPath.Text = filename; 291 } 292 //如果是文件,就执行它 293 else 294 { 295 System.Diagnostics.Process.Start(filename); 296 } 297 } 298 299 /// <summary> 300 /// 根据路径的后缀名控制按钮的状态 301 /// </summary> 302 /// <param name="sender"></param> 303 /// <param name="e"></param> 304 private void txtPath_TextChanged(object sender, EventArgs e) 305 { 306 AddItemsToListView(txtPath.Text); 307 AddHeaderToListView(this.lvwData); 308 } 309 310 /// <summary> 311 /// ListView列表显示样式 312 /// </summary> 313 /// <param name="sender"></param> 314 /// <param name="e"></param> 315 private void ToolStripMenuItem_Click(object sender, EventArgs e) 316 { 317 ToolStripMenuItem tsMenumItem = sender as ToolStripMenuItem; 318 if (tsMenumItem.Checked) 319 { 320 return;//已经选中则返回 321 } 322 else 323 { 324 //清除勾选的右键菜单项 325 ClearCheckState(cmsStyle); 326 //勾选选中的右键菜单项 327 tsMenumItem.Checked = true; 328 } 329 switch (tsMenumItem.Text) 330 { 331 case "大图标": 332 lvwData.View = View.LargeIcon; 333 break; 334 case "详细信息": 335 lvwData.View = View.Details; 336 break; 337 case "小图标": 338 lvwData.View = View.SmallIcon; 339 break; 340 case "列表": 341 lvwData.View = View.List; 342 break; 343 case "平铺": 344 lvwData.View = View.Tile; 345 break; 346 } 347 } 348 349 /// <summary> 350 /// 清除勾选的右键菜单项 351 /// </summary> 352 /// <param name="cms">右键菜单</param> 353 /// <param name="clearAll">是否全部清除</param> 354 private void ClearCheckState(ContextMenuStrip cms, bool clearAll = false) 355 { 356 ToolStripMenuItem tsMenumItemTemp; 357 for (int i = 0; i < cms.Items.Count; i++) 358 { 359 if (!(cms.Items[i] is ToolStripMenuItem)) 360 { 361 continue; 362 } 363 tsMenumItemTemp = cms.Items[i] as ToolStripMenuItem; 364 if (tsMenumItemTemp.Checked) 365 { 366 tsMenumItemTemp.Checked = false; 367 if (!clearAll) 368 { 369 break; 370 } 371 } 372 } 373 } 374 #endregion 375 376 #region 设置ListView的显示样式 377 /// <summary> 378 /// 根据后缀名,设置listview显示样式 379 /// </summary> 380 /// <param name="root">根节点</param> 381 /// <param name="keywords">搜索关键字</param> 382 private void AddItemsToListView(string root, string keywords = "") 383 { 384 //把listview里的所有选项与所有列名都删除 385 lvwData.Clear(); 386 lvwData.BeginUpdate(); 387 //文件 388 if (File.Exists(root)) 389 { 390 AddFileToListView(new FileInfo(root), keywords); 391 } 392 //文件夹 393 else 394 { 395 DirectoryInfo dir = new DirectoryInfo(root); 396 DirectoryInfo[] dirs = dir.GetDirectories(); 397 FileInfo[] files = dir.GetFiles(); 398 //把文件夹信息添加到listview的选项中 399 foreach (DirectoryInfo directoryInfo in dirs) 400 { 401 AddFolderToListView(directoryInfo, keywords); 402 } 403 //把文件夹下文件信息添加到listview的选项中 404 foreach (FileInfo fileInfo in files) 405 { 406 AddFileToListView(fileInfo, keywords); 407 } 408 } 409 this.lvwData.EndUpdate(); 410 } 411 412 /// <summary> 413 /// 将文件添加到ListView中显示 414 /// </summary> 415 /// <param name="fileInfo">文件全路径</param> 416 /// <param name="keywords">搜索关键字</param> 417 private void AddFileToListView(FileInfo fileInfo, string keywords) 418 { 419 ListViewItem lvi = new ListViewItem();//文件项 420 lvi.Tag = fileInfo.FullName; 421 lvi.Text = fileInfo.Name; 422 lvi.ImageIndex = imgLarge.Images.Count - 1; 423 if (keywords != "" && (!lvi.Text.Contains(keywords))) 424 { 425 return;//搜索不到关键字,不将文件添加到ListView中显示 426 } 427 //文件的名称属性项 428 lvi.SubItems[0].Tag = lvi.Tag; 429 lvi.SubItems[0].Text = lvi.Text; 430 //文件大小属性项 431 ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem(); 432 lvsi.Tag = fileInfo.Length; 433 lvsi.Text = fileInfo.Length / 1024 + " KB"; 434 lvi.SubItems.Add(lvsi); 435 //修改日期属性项 436 lvsi = new ListViewItem.ListViewSubItem(); 437 lvsi.Tag = fileInfo.LastAccessTime.ToString(); 438 lvsi.Text = fileInfo.LastAccessTime.ToString(); 439 lvi.SubItems.Add(lvsi); 440 //添加文件 441 this.lvwData.Items.Add(lvi); 442 } 443 444 /// <summary> 445 /// 将文件夹添加到ListView中显示 446 /// </summary> 447 /// <param name="DirectoryInfo">文件夹</param> 448 /// <param name="keywords">搜索关键字</param> 449 private void AddFolderToListView(DirectoryInfo DirectoryInfo, string keywords) 450 { 451 ListViewItem lvi = new ListViewItem(); 452 lvi.Tag = DirectoryInfo.FullName; 453 lvi.Text = DirectoryInfo.Name;//显示名称 454 lvi.ImageIndex = 0; 455 if (keywords != "" && (!lvi.Text.Contains(keywords))) 456 { 457 return;//搜索不到关键字,不将文件夹添加到ListView中显示 458 } 459 // 文件夹的名称属性项 460 lvi.SubItems[0].Tag = lvi.Tag; 461 lvi.SubItems[0].Text = lvi.Text; 462 //文件夹大小属性项 463 ListViewItem.ListViewSubItem lvsi = new ListViewItem.ListViewSubItem(); 464 lvsi.Tag = GetFolderSize(DirectoryInfo); 465 lvsi.Text = FormatFolderSize(folderSize); 466 folderSize = 0;//清零计算文件夹大小的变量 467 lvi.SubItems.Add(lvsi); 468 //修改日期属性项 469 lvsi = new ListViewItem.ListViewSubItem(); 470 lvsi.Tag = DirectoryInfo.LastAccessTime.ToString(); 471 lvsi.Text = DirectoryInfo.LastAccessTime.ToString(); 472 lvi.SubItems.Add(lvsi); 473 //添加文件夹 474 this.lvwData.Items.Add(lvi); 475 } 476 477 /// <summary> 478 /// 递归计算文件夹的大小 479 /// </summary> 480 /// <param name="DirectoryInfo">文件夹</param> 481 /// <returns>文件夹大小</returns> 482 private long GetFolderSize(DirectoryInfo DirectoryInfo) 483 { 484 DirectoryInfo[] dirs = DirectoryInfo.GetDirectories(); 485 FileInfo[] files = DirectoryInfo.GetFiles(); 486 //是文件夹时,继续递归 487 if (dirs.Length > 0) 488 { 489 foreach (DirectoryInfo dir in dirs) 490 { 491 GetFolderSize(dir); 492 } 493 } 494 //是文件时,进行累加计算 495 foreach (FileInfo fi in files) 496 { 497 folderSize = folderSize + fi.Length; 498 } 499 return folderSize; 500 } 501 502 /// <summary> 503 /// 将文件夹大小转化为直观的文字显示 504 /// </summary> 505 /// <param name="size">文件夹大小</param> 506 /// <returns>文件夹大小的文字表示</returns> 507 private string FormatFolderSize(long size) 508 { 509 if ((size >> 20) > 0) 510 { 511 //保留两位小数 512 return ((size >> 10) / 1024.0).ToString("F2") + " MB"; 513 } 514 else 515 { 516 return (size >> 10) + " KB"; 517 } 518 } 519 520 /// <summary> 521 /// 为listview添加列标题 522 /// </summary> 523 private void AddHeaderToListView(ListView listView) 524 { 525 ColumnHeader ch = new ColumnHeader(); 526 ch.Text = "文件名"; 527 ch.Width = 120; 528 listView.Columns.Add(ch); 529 530 ch = new ColumnHeader(); 531 ch.Width = 70; 532 ch.Text = "大小"; 533 listView.Columns.Add(ch); 534 535 ch = new ColumnHeader(); 536 ch.Text = "修改日期"; 537 ch.Width = 140; 538 listView.Columns.Add(ch); 539 } 540 #endregion 541 542 #region 经常使用的公共方法 543 /// <summary> 544 /// 获取文件后缀名(小写) 545 /// </summary> 546 /// <param name="path">文件全路径或文件名</param> 547 public string GetSuffixName(string path) 548 { 549 string suffix = string.Empty; 550 if (path.Contains(".")) 551 { 552 suffix = path.Substring(path.LastIndexOf(".") + 1);//后缀名 553 } 554 return suffix.ToLower(); 555 } 556 557 /// <summary> 558 /// 获取应用程序根路径 559 /// </summary> 560 public static string GetApplicationPath() 561 { 562 string path = Application.StartupPath; 563 string folderName = String.Empty; 564 while (folderName.ToLower() != "bin") 565 { 566 path = path.Substring(0, path.LastIndexOf("\\")); 567 folderName = path.Substring(path.LastIndexOf("\\") + 1); 568 } 569 return path.Substring(0, path.LastIndexOf("\\") + 1); 570 } 571 #endregion 572 } 573 }
1. C#winform中ListView及ContextMenuStrip的使用:http://www.cnblogs.com/makesense/p/4079835.html
2.C#winform点击ListView列标题进行排序:http://bbs.csdn.net/topics/350071962