当前位置: 首页 > news >正文

编程与数学 03-007 《看潮资源管理器》项目开发 07 主窗口设计(3-3)

编程与数学 03-007 《看潮资源管理器》项目开发 07 主窗口设计(3-3)

  • 六、数据呈现:使用DataGridView
    • (一)需求描述
    • (二)初始风格控件
    • (三)网格视图
    • (四)加载数据
    • (五)表格切换
  • 七、状态栏与屏幕参数
    • (一)需求描述
    • (二)属性及成员设置
    • (三)事件及功能代码
  • 全文总结

摘要:本文完整实现《看潮资源管理器》主窗口,包括左右分区、动态菜单、四表切换、快捷键搜索、状态栏、窗体记忆等功能,提供可直接编译的C#与.NET8 WinForm代码,覆盖初始化、数据绑定、事件驱动与配置保存全流程,可作为资源管理类系统界面框架参考。

关键词:WinForm、主窗口布局、FlowLayoutPanel、DataGridView、动态菜单、快捷键、搜索过滤、状态栏、配置保存、资源管理器

六、数据呈现:使用DataGridView

(一)需求描述

在主窗口中,使用DataGridView来展示和操作数据。这在设计器就可以完成。

(二)初始风格控件

这里使用了四个控件:gridSys, gridDisk, gridDir, gridFile。

	private void InitializeDataGridView(){List<DataGridView> dvList = new List<DataGridView>();dvList.AddRange([gridSys, gridDisk, gridDir, gridFile]);foreach (DataGridView dgv in dvList){// DataGridView配置dgv.AutoGenerateColumns = false;dgv.AllowUserToAddRows = false;dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;dgv.Font = new Font("微软雅黑", 12, FontStyle.Regular);dgv.ColumnHeadersDefaultCellStyle.Font = new Font("微软雅黑", 14, FontStyle.Bold);dgv.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;dgv.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;dgv.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2; // 按键或F2进入编辑dgv.RowsDefaultCellStyle.BackColor = Color.LightGreen; // 设置奇偶行不同的背景颜色dgv.AlternatingRowsDefaultCellStyle.BackColor = Color.LightGray;}}

(三)网格视图

/// <summary>
/// 根据数据字典动态构造 DataGridView 的列,并设置样式与行为。
/// 仅生成列结构,不加载实际数据。
/// </summary>
/// <param name="gridData">待初始化的 DataGridView</param>
/// <param name="cuTable">表名(也是字典主键)</param>
private void loadDv(ref DataGridView gridData, string cuTable)
{string sqlCollumn = "";          // 最终 SELECT 子句的列名列表gridData.DataSource = null;      // 先清空数据源gridData.Columns.Clear();        // 再清空旧列/* ---------- 1. 从字典表读取当前表的列定义 ---------- */string sqlDict ="SELECT [Number],[ColumnName],[DataType],[Length],[Prec],[Scale],[InputType]," +"[Width],[Description],[Alignment],[Hide],[Sortable],[Editable],[EditControl]," +"[FormatString],[ToolTip] " +"FROM [dbo].[fm_Dict] " +"WHERE [TableName]=@tablename " +"ORDER BY [Number]";DataTable dtDict = _dbHelper.GetTable(cuTable, sqlDict,new SqlParameter("@tablename", cuTable));/* ---------- 2. 按字典定义逐列构造 ---------- */foreach (DataRow dr in dtDict.Rows){#region 读取字典当前行各字段string columnName   = dr["ColumnName"].ToString();   // 数据库列名string inputtype    = dr["InputType"].ToString();    // 输入类型(预留)int    columnWidth  = (int)dr["Width"];              // 显示宽度string description  = dr["Description"].ToString();  // 表头文字int    alignment    = (int)dr["Alignment"];          // 0左 1中 2右bool   hide         = (bool)dr["Hide"];              // 是否隐藏bool   sortable     = (bool)dr["Sortable"];          // 是否允许点击排序bool   editable     = (bool)dr["Editable"];          // 是否可编辑string formatString = dr["FormatString"].ToString(); // 格式化字符串string tooltip      = dr["ToolTip"].ToString();      // 列提示string editcontrol  = dr["EditControl"].ToString();  // 编辑控件类型// 容错:alignment 只能 0/1/2if (alignment < 0 || alignment > 2) alignment = 0;#endregion#region 构造 SELECT 子句(用于后续加载数据)sqlCollumn += string.IsNullOrEmpty(sqlCollumn)? $"[{columnName}]": $",[{columnName}]";#endregion#region 根据 EditControl 决定列类型if (editcontrol.Equals("CheckBox", StringComparison.OrdinalIgnoreCase)){/* ---- 复选框列 ---- */DataGridViewCheckBoxColumn chkCol = new DataGridViewCheckBoxColumn{Name = columnName,HeaderText = description,DataPropertyName = columnName,ThreeState = false,Width = columnWidth,Visible = !hide,ReadOnly = !editable,SortMode = DataGridViewColumnSortMode.NotSortable,DefaultCellStyle = new DataGridViewCellStyle{ForeColor = Color.Blue,Alignment = DataGridViewContentAlignment.MiddleCenter,Format = formatString}};gridData.Columns.Add(chkCol);}else{/* ---- 文本列 ---- */// 通过 2^alignment*16 把 0/1/2 转成 Left/Center/RightDataGridViewContentAlignment align =(DataGridViewContentAlignment)(Math.Pow(2, alignment) * 16);DataGridViewTextBoxColumn txtCol = new DataGridViewTextBoxColumn{Name = columnName,HeaderText = description,DataPropertyName = columnName,Width = columnWidth,Visible = !hide,ReadOnly = !editable,SortMode = sortable ? DataGridViewColumnSortMode.Automatic: DataGridViewColumnSortMode.NotSortable,DefaultCellStyle = new DataGridViewCellStyle{ForeColor = Color.Blue,Alignment = align,Format = formatString}};gridData.Columns.Add(txtCol);}#endregion/* ---------- 3. 统一设置网格外观 ---------- */gridData.ColumnHeadersHeight = 45;   // 表头高gridData.RowHeadersWidth     = 20;   // 行头宽gridData.RowTemplate.Height  = 40;   // 行高}
}

(四)加载数据

/// <summary>
/// 根据布尔开关,按需重新加载当前所有者的四张核心数据表,
/// 并自动将最新行数写入状态栏 ts5。
/// </summary>
/// <param name="disk">true  重新加载 fm_DriveInfo</param>
/// <param name="dir"> true  重新加载 fm_DirectoryInfo</param>
/// <param name="file">true  重新加载 fm_FileInfo</param>
/// <param name="owner">true  重新加载 fm_Owner</param>
private void loadDt(bool disk, bool dir, bool file, bool owner)
{try{/* ---------- 1. 所有者表 ---------- */if (owner){// 从数据库拉取当前所有者的系统信息dtOwner = _dbHelper.GetOwnerData(cuOwner, "fm_Owner");gridSys.DataSource = dtOwner;   // 直接绑定}/* ---------- 2. 磁盘(存储器)表 ---------- */if (disk){dtDisk = _dbHelper.GetOwnerData(cuOwner, "fm_DriveInfo");gridDisk.DataSource = dtDisk;}/* ---------- 3. 文件夹表 ---------- */if (dir){dtDir = _dbHelper.GetOwnerData(cuOwner, "fm_DirectoryInfo");bdsDir.DataSource = dtDir;      // 先绑定到中间 BindingSourcegridDir.DataSource = bdsDir;    // 再绑定到网格,便于后续排序/过滤}/* ---------- 4. 文件表 ---------- */if (file){dtFile = _dbHelper.GetOwnerData(cuOwner, "fm_FileInfo");bdsFile.DataSource = dtFile;gridFile.DataSource = bdsFile;}/* ---------- 5. 状态栏行数刷新 ---------- */switch (currentProject)   // 0-磁盘 1-文件夹 2-文件 3-系统{case 0: ts5.Text = gridDisk.RowCount.ToString(); break;case 1: ts5.Text = gridDir.RowCount.ToString(); break;case 2: ts5.Text = gridFile.RowCount.ToString(); break;case 3: ts5.Text = gridSys.RowCount.ToString(); break;}}catch (Exception ex){MessageBox.Show("加载所有者数据时:\r\n" + ex.Message,"错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}

(五)表格切换

根据选项按钮,切换到不同的表格。

// 单选框选项变更事件处理:切换到“存储器”视图
private void radioDisk_CheckedChanged(object sender, EventArgs e)
{if (comboOwner.Items.Count <= 0){MessageBox.Show("尚未建立所有者数据,使用所有者维护功能完成设置", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);radioSys.Select();  // 若没有所有者数据,则切换回系统视图return;}if (radioDisk.Checked){ts2.Text = " 存储器 "; // 更新状态栏文本ts3.Text = "使用存储器菜单,完成文件夹或文件名称整理、扫描存储器、数据导入导出等操作";lastProject = currentProject;   // 保存当前项目currentProject = 0; // 设置当前项目为存储器(索引0)recurrentProject(); // 刷新当前项目视图}else return;
}
// 单选框选项变更事件处理:切换到“系统”视图
private void radioSys_CheckedChanged(object sender, EventArgs e)
{if (radioSys.Checked){ts2.Text = " 系统 ";ts3.Text = "使用系统菜单,操作所有者、用户、数据词典等数据";lastProject = currentProject;currentProject = 3; // 设置当前项目为系统(索引3)recurrentProject();}else return;
}
// 单选框选项变更事件处理:切换到“文件”视图
private void radioFile_CheckedChanged(object sender, EventArgs e)
{if (radioFile.Checked){ts2.Text = " 当前管理对象:文件 ";ts3.Text = "Ctrl+N:取消过滤  Ctrl+i:过滤到本级 Ctrl+u:过滤到上级 Ctrl+T:条件过滤  Ctrl+L:过滤选定 双击行:转到Windows资源管理器";lastProject = currentProject;currentProject = 2; // 设置当前项目为文件(索引2)recurrentProject();}else return;
}
// 单选框选项变更事件处理:切换到“文件夹”视图
private void radioDir_CheckedChanged(object sender, EventArgs e)
{if (radioDir.Checked){ts2.Text = " 文件夹 ";ts3.Text = "Ctrl+N:取消过滤 Ctrl+1-6 级次过滤 Ctrl+i:过滤到本级 Ctrl+u:过滤到上级 Ctrl+T:条件过滤  Ctrl+L:过滤选定 双击行:转到Windows资源管理器";lastProject = currentProject;currentProject = 1; // 设置当前项目为文件夹(索引1)recurrentProject();}else return;
}

七、状态栏与屏幕参数

(一)需求描述

需要在窗口底部显示一个状态栏,以显示当前程序运行及操作状态。

(二)属性及成员设置

// 
// statusStripfm
// 
statusStripfm.Font = new Font("微软雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point, 134);
statusStripfm.ImageScalingSize = new Size(20, 20);
statusStripfm.Items.AddRange(new ToolStripItem[] { ts1, ts2, ts3, ts5, tsR });
statusStripfm.Location = new Point(0, 594);
statusStripfm.Name = "statusStripfm";
statusStripfm.Padding = new Padding(2, 0, 20, 0);
statusStripfm.Size = new Size(1784, 27);
statusStripfm.TabIndex = 13;
statusStripfm.Text = "ss1";
// 
// ts1
// 
ts1.Margin = new Padding(3);
ts1.Name = "ts1";
ts1.Size = new Size(90, 21);
ts1.Text = "当前所有者";
ts1.TextAlign = ContentAlignment.MiddleLeft;
// 
// ts2
// 
ts2.Margin = new Padding(3);
ts2.Name = "ts2";
ts2.Size = new Size(74, 21);
ts2.Text = "当前类别";
// 
// ts3
// 
ts3.Margin = new Padding(3);
ts3.Name = "ts3";
ts3.Size = new Size(1231, 21);
ts3.Spring = true;
ts3.Text = "记录数";
ts3.TextAlign = ContentAlignment.MiddleLeft;
// 
// ts5
// 
ts5.Margin = new Padding(3);
ts5.Name = "ts5";
ts5.Size = new Size(74, 21);
ts5.Text = "当前操作";
// 
// tsR
// 
tsR.Margin = new Padding(3);
tsR.Name = "tsR";
tsR.Size = new Size(263, 21);
tsR.Text = " 看潮资源管理器  作者:明月看潮生  ";
tsR.TextAlign = ContentAlignment.MiddleRight;
//以上代码来自设计器文件

(三)事件及功能代码

/// <summary>
/// 状态栏与屏幕参数
/// </summary>private bool recurrentProject()
{// 根据上一个项目类型保存对应的DataGridView设置switch (lastProject){case 0:SaveFormSettingsdgv(ref gridDisk);break;case 1:SaveFormSettingsdgv(ref gridDir);break;case 2:SaveFormSettingsdgv(ref gridFile);break;case 3:SaveFormSettingsdgv(ref gridSys);break;}// 根据当前项目类型显示对应的菜单和DataGridViewsysMenu.Visible = (currentProject == 3);gridSys.Visible = (currentProject == 3);fileMenu.Visible = (currentProject == 2);gridFile.Visible = (currentProject == 2);dirMenu.Visible = (currentProject == 1);gridDir.Visible = (currentProject == 1);diskMenu.Visible = (currentProject == 0);gridDisk.Visible = (currentProject == 0);// 根据当前项目类型更新状态栏显示的行数switch (currentProject){case 0:ts5.Text = gridDisk.RowCount.ToString();break;case 1:ts5.Text = gridDir.RowCount.ToString();break;case 2:ts5.Text = gridFile.RowCount.ToString();break;case 3:ts5.Text = gridSys.RowCount.ToString();break;}return true;
}
// 从文件加载保存设置的状态
private void LoadSavedSeting()
{saveSeting = true;  // 默认启用设置保存if (File.Exists(CredentialsFilePath)){try{string[] lines = File.ReadAllLines(CredentialsFilePath);saveSeting = bool.Parse(lines[3]);  // 从文件第四行读取设置状态}catch{}}
}
// 保存窗体位置、大小和状态
public void SaveFormSettingsfm()
{try{if (saveSeting != true) return; // 检查是否启用设置保存if (fmactivated != true) return;    // 检查窗体是否已激活// 保存窗体位置和大小、状态。string fmset = $"{(int)this.WindowState}," +$"{this.Top},{this.Left},{this.Width},{this.Height}";_myScreen.FmSave(this.Name, fmset,"WindowState,Top,Left,Width,Height");}catch (Exception ex){MessageBox.Show("保存窗口参数时出错:\r\n" + ex.Message, "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
// 保存DataGridView的列宽、行高等设置
public void SaveFormSettingsdgv(ref DataGridView dgv)
{try{if (saveSeting != true) return; // 检查是否启用设置保存if (fmactivated != true) return;    // 检查窗体是否已激活if (dgv.Rows.Count <= 0) return;    // 检查是否有行数据string rowheight = dgv.Rows[0].Height.ToString().Trim();// 保存表格标头高度、行标宽度、行高。string fmset = $"{dgv.ColumnHeadersHeight},{dgv.RowHeadersWidth},{rowheight}";_myScreen.FmSave(this.Name + "_GridHeaders_" + dgv.Name, fmset,"ColumnHeadersHeight,RowHeadersWidth,RowHeight");// 如果 DataGridView 不为空且有行if (dgv != null && dgv.RowCount > 0){// 保存 DataGridView 列宽string gdset = dgv.Columns[0].Width.ToString();string gdmemo = dgv.Columns[0].HeaderText;for (int g = 1; g < dgv.Columns.Count; g++){int cw = -1;if (dgv.Columns[g].Visible){cw = dgv.Columns[g].Width;}gdset += "," + cw.ToString();gdmemo += "," + dgv.Columns[g].HeaderText;}_myScreen.FmSave(this.Name + "_" + "GridColumnsWidth_" + dgv.Name, gdset, gdmemo);}}catch (Exception ex){MessageBox.Show("保存表格参数时出错:\r\n" + ex.Message, "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
// 加载窗体位置、大小和状态设置
public void LoadFormSettingsfm()
{try{string fmset = _myScreen.FmRead(this.Name);string[] fmay = fmset.Split(',');short ws = 0;if (fmay.Length != 5) return;   // 检查参数完整性ws = short.Parse(fmay[0]);if (ws == 2) this.WindowState = FormWindowState.Maximized;  // 最大化状态if (ws == 0)    // 正常状态{if (int.Parse(fmay[1]) > 0) this.Top = int.Parse(fmay[1]);if (int.Parse(fmay[2]) > 0) this.Left = int.Parse(fmay[2]);if (int.Parse(fmay[3]) > 50) this.Width = int.Parse(fmay[3]);if (int.Parse(fmay[4]) > 50) this.Height = int.Parse(fmay[4]);}}catch (Exception ex){MessageBox.Show("加载窗口参数时出错:\r\n" + ex.Message, "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
// 加载DataGridView的列宽、行高等设置
public void LoadFormSettingsdgv(ref DataGridView dgv)
{try{string fmset = _myScreen.FmRead(this.Name + "_GridHeaders_" + dgv.Name);string[] fmay = fmset.Split(',');if (fmay.Length != 3) return;   // 检查参数完整性if (int.Parse(fmay[0]) > 10) dgv.ColumnHeadersHeight = int.Parse(fmay[0]);if (int.Parse(fmay[1]) > 10) dgv.RowHeadersWidth = int.Parse(fmay[1]);if (int.Parse(fmay[2]) > 10) dgv.RowTemplate.Height = int.Parse(fmay[2]);fmset = _myScreen.FmRead(this.Name + "_" + "GridColumnsWidth_" + dgv.Name);fmay = fmset.Split(',');if (dgv != null){if (fmay.Length == dgv.Columns.Count)   // 检查列数匹配{for (int c = 0; c < dgv.Columns.Count; c++){int cw = int.Parse(fmay[c]);if (cw <= 0)    // 宽度为负表示隐藏列{dgv.Columns[c].Visible = false;}else{dgv.Columns[c].Width = cw;}}}}}catch (Exception ex){MessageBox.Show("加载表格参数时出错:\r\n" + ex.Message, "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
// 窗体关闭时的处理事件
protected override void OnFormClosing(FormClosingEventArgs e)
{if (saveSeting == true) // 如果启用设置保存{// 根据当前项目类型保存对应的DataGridView设置switch (currentProject){case 0:SaveFormSettingsdgv(ref gridDisk);break;case 1:SaveFormSettingsdgv(ref gridDir);break;case 2:SaveFormSettingsdgv(ref gridFile);break;case 3:SaveFormSettingsdgv(ref gridSys);break;}SaveFormSettingsfm();   // 保存窗体设置_myScreen.FmWrite("FormMain");  // 写入设置到文件}// 停止并释放文件监视器insertWatcher?.Stop();removeWatcher?.Stop();insertWatcher?.Dispose();removeWatcher?.Dispose();base.OnFormClosing(e);  // 调用基类方法
}

全文总结

本文围绕《看潮资源管理器》主窗口的实战需求,从零开始给出了一套可直接落地的C# WinForm方案。首先通过Anchor与Dock组合完成左右分栏,左侧FlowLayoutPanel嵌入四组GroupBox按钮菜单,右侧动态切换gridSys/gridDisk/gridDir/gridFile四张DataGridView,实现“系统-存储器-文件夹-文件”四级数据的无缝跳转。菜单采用CreateGroupBox工厂方法批量生成,文本、提示、事件一站式绑定,配合RunMenu路由函数,将三十余项业务功能集中调度。数据层面,先以fm_Dict字典表驱动列自动生成,再借BindingSource实现排序、过滤与编辑;状态栏实时反馈当前所有者、类别、记录数与操作提示;搜索框支持Enter逐条定位,Ctrl组合键提供全选、清除、多级目录筛选、条件过滤等快捷操作。窗体与网格的宽高、列宽、行高等视觉参数全部序列化到本地,启动自动还原。USB插拔监视、所有者下拉切换、异步扫描与查重算法均被封装为独立模块,与界面线程解耦。整套代码遵循“设计器+分部类+业务扩展”的三层结构,逻辑与UI分离,既保证Visual Studio可视化编辑,又支持后续功能横向扩展。开发者可直接复制BuildMenu、loadDv、FormMain_KeyDown等核心方法,快速搭建自己的资源管理、资产盘点或数据审计系统,并借字典表机制实现字段、宽度、对齐、编辑控件等细节的可配置化,显著降低后期维护成本。

http://www.dtcms.com/a/499324.html

相关文章:

  • 基于单片机的架空线路接地故障检测与报警系统
  • 鸿蒙实现滴滴出行项目之乘客支付订单功能
  • 如何把自己做的网站放到网上360建筑网怎样取消发布的消息
  • 做网站有哪个空间网站建设优化推广贵州
  • 西电25年A测 语音识别机械臂方案与教程
  • 数据结构——队列的链式存储结构
  • 媒体135网站口碑好的宜昌网站建设
  • 湖南省建设银行网站官网深圳龙华网站建设公司
  • 网站后台管理系统源码网站空间文件夹
  • 元宇宙与公共服务的深度融合:重构民生服务的效率与温度
  • 深入解析十字链表:从理论到实践的全面指南
  • 红色页面网站护肤品网站建设的摘要
  • GB28181视频服务wvp部署(一)
  • 吴忠住房和城乡建设局网站小学生编程网课前十名
  • 浅谈 OpenAPI Schema—— 接口契约的标准语言
  • TSDF 体素模型与光线投射
  • 【学习笔记】利用meshlab进行曲面的质量检查
  • S2--单链表
  • jdk.random 包详解
  • 如何做网站接口关于电子商务网站建设的现状
  • 网站栏目设计内容谷歌在线浏览器入口
  • 聊聊 Unity(小白专享、C# 小程序 之 自动更新)
  • 截取网站流量dede购物网站
  • 某Boss直聘数据获取
  • Spring Boot 3零基础教程,WEB 开发 默认欢迎页 笔记28
  • Redis极简入门 整合springboot
  • 漫蛙漫画官网入口 - 免费漫画在线看|防走失页入口
  • MySQL中的约束详解
  • 服务流程企业网站东莞市建设安监监督网站
  • leetcode 206. 反转链表 python