编程与数学 03-007 《看潮资源管理器》项目开发 17 查找、选定、过滤和导航 (4-4)
摘要: 本文实现《看潮资源管理器》查找、选定、过滤与导航共性操作:搜索框回车即时增量匹配,支持循环查找与快捷键Ctrl+F;提供全选、全清、条件选择及IsSelect布尔列;可按目录级次、关键词、选择状态三层过滤;双击行即可在资源管理器定位并高亮文件或文件夹,辅以Ctrl+U/I快速上下级导航,完整覆盖数据浏览需求。
关键词: 增量搜索、快捷键、全选全清、级次过滤、关键词过滤、选择状态过滤、双击定位、资源管理器、目录导航、DataGridView
四、导航
(一)需求描述
条件查找不一定要选定,有时只是要导航到相应数据行的位置,然后再由用户决定是否要选定操作,所以导航也是数据浏览的一个必要功能。
(二)功能代码
private void SelectCell(ref DataGridView dgv, ref DataGridViewRow row, string columnName)
{
// 清除现有选择
dgv.ClearSelection();
// 选中整行(可选)
row.Selected = true;
// 选中特定单元格
DataGridViewCell cell = row.Cells[columnName];
cell.Selected = true;
// 滚动到该单元格
dgv.CurrentCell = cell;
dgv.FirstDisplayedScrollingRowIndex = row.Index;
}
// 根据当前选中项过滤目录显示(支持向上/向下导航)
private void DirectoryTo(bool ui)
{
// 根据当前项目类型进行处理(项目1处理文件夹,项目2处理文件)
if (currentProject == 1)
{
// 获取当前选中的单元格
DataGridViewCell cell = gridDir.CurrentCell;
if (cell == null) return;
if (cell.RowIndex < 0 || cell.ColumnIndex < 0) return;
// 获取目录名
string cellstring = gridDir.Rows[cell.RowIndex].Cells["DirectoryName"].Value.ToString();
if (cellstring == string.Empty) return;
if (ui == true)
{
// UI模式:导航到父目录
int dirlength = cellstring.Split("\\").Length;
if (dirlength < 2)
{
// 如果目录层级小于2,清除过滤器
bdsDir.Filter = null;
}
else
{
// 获取父目录路径并设置过滤器
int lastSeparator = cellstring.LastIndexOf("\\");
if (lastSeparator > 0)
{
string parentPath = cellstring.Substring(0, lastSeparator);
bdsDir.Filter = $"DirectoryName like '{parentPath}%'";
}
}
}
else
{
// 非UI模式:导航到子目录
bdsDir.Filter = $"DirectoryName like '{cellstring}%'";
}
// 更新状态栏显示行数
ts5.Text = gridDir.RowCount.ToString();
return;
}
if (currentProject == 2)
{
// 处理文件网格的逻辑与文件夹类似
DataGridViewCell cell = gridFile.CurrentCell;
if (cell == null) return;
if (cell.RowIndex < 0 || cell.ColumnIndex < 0) return;
string cellstring = gridFile.Rows[cell.RowIndex].Cells["DirectoryName"].Value.ToString();
if (cellstring == string.Empty) return;
if (ui == true)
{
int dirlength = cellstring.Split("\\").Length;
if (dirlength < 2)
{
bdsFile.Filter = null;
}
else
{
int lastSeparator = cellstring.LastIndexOf("\\");
if (lastSeparator > 0)
{
string parentPath = cellstring.Substring(0, lastSeparator);
bdsFile.Filter = $"DirectoryName like '{parentPath}%'";
}
}
}
else
{
bdsFile.Filter = $"DirectoryName like '{cellstring}%'";
}
ts5.Text = gridFile.RowCount.ToString();
return;
}
}
private void gridDir_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
// 检查点击的是有效的数据行(排除表头)
if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
// 获取选中行的路径信息
string driveLetter = gridDir.Rows[e.RowIndex].Cells["DriveLetter"].Value.ToString();
string directory = gridDir.Rows[e.RowIndex].Cells["DirectoryName"].Value.ToString();
string name = gridDir.Rows[e.RowIndex].Cells["Name"].Value.ToString();
if (driveLetter == string.Empty || name == string.Empty) return;
// 构建完整路径
string path = string.IsNullOrEmpty(directory) ?
Path.Combine(driveLetter, name) :
Path.Combine(driveLetter, directory + "\\" + name);
// 检查文件夹是否存在
if (Directory.Exists(path))
{
// 在Windows资源管理器中打开并选中该文件夹
Process.Start("explorer.exe", $"/select,\"{path}\"");
}
else
{
MessageBox.Show("存储器未连接或当前文件夹已经不存在!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
// 双击行时使用系统程序打开文件
private void gridFile_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
// 检查双击的单元格是否是有效的数据行(排除表头行和表头列)
if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
// 从双击的行中获取文件路径信息
string driveLetter = gridFile.Rows[e.RowIndex].Cells["DriveLetter"].Value.ToString();
string directory = gridFile.Rows[e.RowIndex].Cells["DirectoryName"].Value.ToString();
string name = gridFile.Rows[e.RowIndex].Cells["Name"].Value.ToString();
// 检查必要的路径组成部分是否为空,如果为空则直接返回
if (driveLetter == string.Empty || directory == string.Empty || name == string.Empty) return;
// 构建完整的文件路径:驱动器盘符 + 目录路径 + 文件名
string path = Path.Combine(driveLetter, directory + "\\" + name);
// 检查文件是否实际存在于磁盘上
if (File.Exists(path))
{
// 文件存在,在Windows资源管理器中打开并选中该文件
// 使用explorer.exe的/select参数可以高亮显示指定文件
Process.Start("explorer.exe", $"/select,\"{path}\"");
}
else
{
// 文件不存在,显示提示信息
// 可能的原因:外部存储器未连接、文件已被删除或移动
MessageBox.Show("存储器未连接或当前文件已经不存在!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
这段代码是一个文件/目录管理系统的核心功能实现,主要包含三个方法:
1. SelectCell 方法
private void SelectCell(ref DataGridView dgv, ref DataGridViewRow row, string columnName)
功能:在DataGridView中精确选择特定单元格
- 清除所有现有选择
- 选中整行
- 选中指定列名的单元格
- 滚动到该单元格位置确保可见
2. DirectoryTo 方法
private void DirectoryTo(bool ui)
功能:根据当前选中项进行目录导航过滤
逻辑流程:
-
currentProject == 1(目录模式):
ui == true:向上导航到父目录(设置过滤器显示父目录内容)ui == false:向下导航到子目录(设置过滤器显示子目录内容)
-
currentProject == 2(文件模式):
- 类似目录模式的过滤逻辑,但应用于文件网格
过滤原理:使用SQL-like的过滤器语法 DirectoryName like '路径%'
3. 双击事件处理
gridDir_CellDoubleClick
功能:双击目录行时在资源管理器中打开对应文件夹
- 构建完整路径:
驱动器盘符 + 目录路径 + 文件夹名 - 检查文件夹是否存在
- 使用
explorer.exe /select命令高亮显示该文件夹
gridFile_CellDoubleClick
功能:双击文件行时在资源管理器中选中对应文件
- 构建完整路径:
驱动器盘符 + 目录路径 + 文件名 - 检查文件是否存在
- 使用
explorer.exe /select命令高亮显示该文件
系统特点
- 双模式支持:同时管理文件夹和文件
- 路径导航:支持向上/向下目录层级导航
- 可视化交互:与Windows资源管理器集成
- 错误处理:检查存储设备连接状态和文件存在性
这个系统类似于一个简化的文件浏览器,提供了基于DataGridView的图形化文件管理界面。
全文总结
本章聚焦文件夹与文件的共性交互,设计统一搜索框与全局快捷键体系。回车触发增量查找,自动循环并高亮下一个匹配单元格;Ctrl+F立即执行搜索,Ctrl+1~6按级次筛选,Ctrl+U/I实现上下级目录跳转。选定功能提供“全部”“清除”按钮与IsSelect复选框列,支持条件选择与反向过滤。过滤模块集成三级策略:目录层级、文本关键词、选择状态,可叠加使用,实时更新状态栏计数。导航部分通过SelectCell确保目标行可见;双击行调用explorer.exe /select直接定位磁盘实体,若存储器未连接给出友好提示。所有功能按currentProject切换网格对象,SQL-like Filter语法实现后台筛选,UI与数据源保持同步。代码兼顾性能与体验,大量数据下分批刷新,键盘鼠标并重,满足快速查找、批量标记、灵活筛选与直观定位的综合需求,为后续批量重命名、统计、导出等操作奠定交互基础。
1375

被折叠的 条评论
为什么被折叠?



