编程与数学 03-008 《看潮企业管理软件》项目开发 04 主窗口 3-3
摘要:《看潮企业管理软件》主窗口采用Ribbon+导航+工作区三栏布局,通过动态加载图标菜单实现角色驱动的权限控制。核心代码FmMain.cs定义了状态变量、数据表和UI组件,采用事件驱动架构集成任务流、皮肤切换等功能模块,展示了ERP系统主控台的现代化实现方案。
编程与数学 03-008 《看潮企业管理软件》项目开发 04 主窗口 3-3
摘要:本文围绕《看潮企业管理软件》主窗口设计展开,提出“角色驱动、任务分区、权限过滤”三原则,用Ribbon+左导航+右工作区布局,动态加载图标与菜单,集成任务流、皮肤、参数持久化,兼顾高效操作与可扩展性,为ERP界面现代化提供完整范例。
关键词:ERP主窗口、角色驱动、Ribbon界面、动态权限、任务流、DevExpress、可扩展性、用户体验
人工智能助手:DeepSeek、Kimi
五、窗体功能代码
功能代码是开发过程中编写的窗口初始化代码和事件代码、窗口过程和函数等。在VS2022中,基本的程序框架也是自动生成的。
下面给出本项目的第一个复杂代码,主窗口功能代码,部分内容需要以后的内容加以说明,可以先行阅读代码,来了解做为主窗口需要完成的处理。
/*
* 文件:FmMain.cs
* 功能:看潮ERP主窗口
* 说明:该窗口为软件运行的主窗口
*/
using DevExpress.Utils;
using DevExpress.Utils.Menu;
using DevExpress.XtraBars;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraLayout;
using DevExpress.XtraTab;
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using static KcErp.KcDb;
using static KcErp.KcEditgd;
using static KcErp.KcMain;
namespace KcErp
{
/// <summary>
/// ERP系统主窗口类
/// 继承自DevExpress的RibbonForm,提供带功能区的高级窗口界面
/// 这是整个ERP系统的核心容器和总控制台
/// </summary>
public partial class FmMain : DevExpress.XtraBars.Ribbon.RibbonForm
{
#region 窗口变量
// 以下是主窗口使用的核心变量,用于存储状态、数据和UI组件引用
public static GridView rwgv = new GridView(); // “我的任务”表格视图,用于显示待办任务列表
public static GridView ztgv = new GridView(); // “系统状态”表格视图,用于监控系统状态
public string cslj; // 系统配置和文件存储的根路径(如:C:\ProgramData\KcErp\FormCs\)
public DataTable dtgntp; // 功能模块图标数据表,存储各功能模块对应的图标信息
public string fmset; // 窗口设置信息字符串,用于序列化/反序列化窗口状态
public ImageCollection gnimage = new ImageCollection(); // 功能图标集合,存储所有功能模块的图标
public LayoutControl jclc = new LayoutControl(); // “基础资料”面板的布局控件,用于动态生成功能按钮布局
public int pczts; // 程序状态标志,用于跟踪应用程序的运行时状态
public bool pquit = false; // 退出标志,为true时表示正在退出程序,防止重复清理操作
public RepositoryItemButtonEdit[] rcbt; // 任务列表中操作按钮的编辑器控件数组,每个任务可能有不同的操作按钮
public string[] rcbtmc; // 操作按钮名称数组,与rcbt数组对应,存储按钮的显示文本
public RepositoryItemTextEdit rctt = new RepositoryItemTextEdit(); // 默认文本编辑器,用于任务列表中没有自定义按钮的单元格
public string sqmk = ""; // 授权模块字符串,存储用户有权限访问的模块列表(以逗号分隔)
public LayoutControl xxlc = new LayoutControl(); // “信息查询”面板的布局控件
public LayoutControl ywlc = new LayoutControl(); // “业务处理”面板的布局控件
#endregion 窗口变量
public bool gnyx = false; // 功能运行状态标志,为true时表示某个功能正在运行,防止重复激活
/// <summary>
/// 主窗口构造函数
/// 初始化窗口组件并绑定所有事件处理器
/// 这是窗口生命周期的起点
/// </summary>
public FmMain()
{
// 初始化窗体组件(由设计器生成的代码)
InitializeComponent();
// 绑定Ribbon功能区按钮点击事件
// 每个按钮点击都会触发相应的业务功能
this.BarBQXX.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarBQXX_ItemClick);
this.BarGNLB.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarGNLB_ItemClick);
this.BarFLML.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarFLML_ItemClick);
this.BarCXSR.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarCXSR_ItemClick);
this.BarGLSR.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarGLSR_ItemClick);
this.BarDJSR.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarDJSR_ItemClick);
this.BarYWCL.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarYWCL_ItemClick);
this.BarDJSP.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarDJSP_ItemClick);
this.BarDJCX.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarDJCX_ItemClick);
this.BarHZCX.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarHZCX_ItemClick);
this.Barexit.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarEXIT_ItemClick);
this.BarHELP.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarHELP_ItemClick);
this.Barhelpsj.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarHELPSJ_ItemClick);
this.BarExitsj.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarExitSj_ItemClick);
this.BarYHXX.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarYHXX_ItemClick);
this.BarSKIN.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarSKIN_ItemClick);
this.BarSJLJ.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarSJLJ_ItemClick);
this.BarWjxz.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarWjxz_ItemClick);
this.BarYHMM.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarYHMM_ItemClick);
this.BarZTLJ.ItemClick += new DevExpress.XtraBars.ItemClickEventHandler(this.BarZTLJ_ItemClick);
// 绑定BarEditItem值变更事件(这些是功能区中的编辑控件)
this.BarDqpt.EditValueChanged += new System.EventHandler(this.Bardqpt_EditValueChanged); // 打印机选择变更
this.Tsywrq.EditValueChanged += new System.EventHandler(this.TsYwrq_EditValueChanged); // 业务日期变更
// 绑定普通按钮点击事件
this.Btrwmw.Click += new System.EventHandler(this.Btrwmw_Click); // 刷新任务列表按钮
// 绑定窗体生命周期事件
this.Activated += new System.EventHandler(this.Form_Activated); // 窗体激活时触发
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form_FormClosing); // 窗体关闭时触发
this.Load += new System.EventHandler(this.Form_Load); // 窗体加载时触发
}
/// <summary>
/// 创建文本文件的通用工具方法
/// 主要用于生成日志文件、配置文件等
/// </summary>
/// <param name="filename">要创建的文件完整路径</param>
/// <param name="texttoadd">要写入文件的文本内容</param>
public static void CreateTextFile(string filename, string texttoadd)
{
// 使用UTF-8编码创建或覆盖文件
StreamWriter swfromfile = new StreamWriter(filename, false, System.Text.Encoding.UTF8);
swfromfile.Write(texttoadd); // 写入文本内容
swfromfile.Flush(); // 清空缓冲区,确保数据写入磁盘
swfromfile.Close(); // 关闭文件流
}
/// <summary>
/// 动态配置网格视图列的核心方法
/// 根据数据字典(x9_sjzd表)中的定义,为网格列创建不同类型的编辑器
/// 支持按钮编辑器、复选框、日期选择器、文本编辑器等多种控件类型
/// </summary>
/// <param name="gd">网格控件引用</param>
/// <param name="gv">网格视图引用</param>
/// <param name="dtzd">数据字典DataTable,包含列定义信息</param>
public static void Gdlomyrw(ref GridControl gd, ref GridView gv, ref DataTable dtzd)
{
try
{
// 定义列配置变量
string tedit; // 编辑控件类型:buttonedit/checkedit/dateedit/textread等
string tfname; // 数据库字段名
string tftype; // 字段数据类型
string tfmemo; // 字段说明(显示为列标题)
string tsrlx; // 输入类型
string tformattype; // 格式类型(如DateTime、Numeric)
string tformatstr; // 格式字符串(如"yyyy-MM-dd")
int alignment; // 对齐方式(0:左对齐, 1:居中, 2:右对齐)
DataRow[] dr = null; // 存储查询到的列配置
int cols; // 网格列数
cols = gv.Columns.Count;
// 遍历网格的所有列,为每列配置相应的编辑器
for (int i = 0; i <= cols - 1; i++)
{
// 在数据字典中查找当前列的配置
dr = dtzd.Select("fname='" + gv.Columns[i].FieldName + "'");
string gcname = gv.Columns[i].Name;
// 如果数据字典中没有该列的配置
if (dr.Length <= 0)
{
// 创建默认的文本编辑器(只读)
RepositoryItemTextEdit rc = new RepositoryItemTextEdit();
rc.Appearance.TextOptions.WordWrap = WordWrap.Wrap; // 允许文本换行
gd.RepositoryItems.Add(rc); // 添加到网格的编辑器集合
gv.Columns[i].ColumnEdit = rc; // 绑定到当前列
gv.Columns[i].OptionsColumn.AllowSort = DefaultBoolean.False; // 禁用排序
gv.Columns[i].OptionsColumn.AllowMove = false; // 禁用列移动
gv.Columns[i].OptionsFilter.AllowFilter = false; // 禁用筛选
gv.Columns[i].OptionsColumn.ReadOnly = true; // 设置为只读
}
else
{
// 从数据字典中读取列配置
tfmemo = dr[0]["fmemo"].ToString();
tedit = dr[0]["edit"].ToString();
tfname = dr[0]["fname"].ToString();
tftype = dr[0]["ftype"].ToString();
tsrlx = dr[0]["srlx"].ToString();
tformattype = dr[0]["formattype"].ToString();
tformatstr = dr[0]["formatstr"].ToString();
alignment = Convert.ToInt32(dr[0]["alignment"]);
// 根据编辑类型创建不同的编辑器控件
switch (tedit)
{
case "buttonedit": // 按钮编辑器(通常用于打开选择对话框)
{
RepositoryItemButtonEdit rc = new RepositoryItemButtonEdit
{
TextEditStyle = TextEditStyles.Standard, // 标准文本编辑样式
MaxLength = 0 // 不限制输入长度
};
// 如果有格式定义,设置显示格式
if (tformattype != "" && tformatstr != "")
{
rc.DisplayFormat.FormatType = Tf(tformattype); // 显示格式类型
rc.DisplayFormat.FormatString = tformatstr; // 显示格式字符串
rc.EditFormat.FormatType = Tf(tformattype); // 编辑格式类型
rc.EditFormat.FormatString = tformatstr; // 编辑格式字符串
}
// 如果是选择类型,禁用文本编辑
rc.TextEditStyle = (tformatstr.ToLower() == "select" ?
TextEditStyles.DisableTextEditor : TextEditStyles.Standard);
gd.RepositoryItems.Add(rc);
gv.Columns[i].ColumnEdit = rc;
break;
}
case "checkedit": // 复选框编辑器(可编辑)
case "checkread": // 复选框编辑器(只读)
{
RepositoryItemCheckEdit rc = new RepositoryItemCheckEdit();
gd.RepositoryItems.Add(rc);
gv.Columns[i].ColumnEdit = rc;
break;
}
case "dateedit": // 日期选择编辑器
{
RepositoryItemDateEdit rc = new RepositoryItemDateEdit();
// 设置日期格式
if (tformattype != "" && tformatstr != "")
{
rc.DisplayFormat.FormatType = Tf(tformattype);
rc.DisplayFormat.FormatString = tformatstr;
rc.EditFormat.FormatType = Tf(tformattype);
rc.EditFormat.FormatString = tformatstr;
}
gd.RepositoryItems.Add(rc);
gv.Columns[i].ColumnEdit = rc;
gv.Columns[i].OptionsColumn.AllowEdit = false; // 禁用编辑
break;
}
default: // 默认文本编辑器("textread"等)
{
RepositoryItemTextEdit rc = new RepositoryItemTextEdit();
rc.Appearance.TextOptions.WordWrap = WordWrap.Wrap;
// 设置文本格式
if (tformattype != "" && tformatstr != "")
{
rc.DisplayFormat.FormatType = Tf(tformattype);
rc.DisplayFormat.FormatString = tformatstr;
rc.EditFormat.FormatType = Tf(tformattype);
rc.EditFormat.FormatString = tformatstr;
}
gd.RepositoryItems.Add(rc);
gv.Columns[i].ColumnEdit = rc;
break;
}
}
// 设置列的对齐方式
Setag(ref gv, i, alignment);
// 设置列标题
gv.Columns[i].Caption = tfmemo;
// 设置列属性
gv.Columns[i].OptionsColumn.AllowSort = DefaultBoolean.False;
gv.Columns[i].OptionsColumn.AllowMove = true;
gv.Columns[i].OptionsFilter.AllowFilter = false;
// 在Tag中存储编辑类型,供后续使用
gv.Columns[i].Tag = tedit;
}
// 设置列标题的样式
gv.Columns[i].AppearanceHeader.Options.UseTextOptions = true;
gv.Columns[i].AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center; // 水平居中
gv.Columns[i].AppearanceHeader.TextOptions.VAlignment = VertAlignment.Center; // 垂直居中
gv.Columns[i].AppearanceHeader.TextOptions.WordWrap = WordWrap.Wrap; // 允许换行
}
}
catch (Exception ex)
{
// 异常处理:显示详细的错误信息
MsgExShow("初始我的任务表格视图", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 重新登录方法
/// 保存当前窗口参数后重启应用程序,用于切换账套或重新连接后恢复工作环境
/// </summary>
public void ReLogin()
{
try
{
// 如果不是"否"模式(表示需要保存窗口参数)
if (pFMSD == "否")
{
if (pDSFM != null)
{
if (pDSFM.Tables.Count > 0)
{
try
{
// 将窗口参数保存到XML文件(按数据库名和屏幕分辨率命名)
pDSFM.WriteXml(cslj + pDBmc + "_" + myscreen + ".xml");
pDSFM.AcceptChanges(); // 接受更改,标记为未修改状态
}
catch (Exception ex)
{
MsgExShow("提交窗口参数", ex.Message, ex.Source, ex.StackTrace);
}
}
}
}
Application.Restart(); // 重启整个应用程序
}
catch (Exception)
{
// 静默处理异常,避免重启失败时造成程序崩溃
}
}
/// <summary>
/// 版权信息按钮点击事件
/// 显示关于窗口,展示软件版本、版权等信息
/// </summary>
private void BarBQXX_ItemClick(object sender, ItemClickEventArgs e)
{
FmAbout xf = new FmAbout(); // 创建关于窗口实例
xf.LZTMC.Text = pZTMC; // 设置账套名称
xf.ShowDialog(this); // 以模态方式显示关于窗口
xf.Dispose(); // 释放窗口资源
}
/// <summary>
/// 查询输入功能定义按钮点击事件
/// 打开查询输入功能的定义界面
/// </summary>
private void BarCXSR_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("查询输入"); // 调用通用方法打开功能定义窗口
}
/// <summary>
/// 单据查询功能定义按钮点击事件
/// 打开单据查询功能的定义界面
/// </summary>
private void BarDJCX_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("单据查询");
}
/// <summary>
/// 单据审批功能定义按钮点击事件
/// 打开单据审批功能的定义界面
/// </summary>
private void BarDJSP_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("单据审批");
}
/// <summary>
/// 单据输入功能定义按钮点击事件
/// 打开单据输入功能的定义界面
/// </summary>
private void BarDJSR_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("单据输入");
}
/// <summary>
/// 当前打印机选择变更事件
/// 当用户在功能区更改打印机时更新全局打印机设置
/// </summary>
private void Bardqpt_EditValueChanged(object sender, EventArgs e)
{
try
{
pPrinterName = BarDqpt.EditValue.ToString(); // 更新全局打印机名称变量
}
catch (Exception)
{
// 静默处理异常,避免因打印机设置问题导致程序崩溃
}
}
/// <summary>
/// 退出按钮点击事件(账套模式)
/// 关闭主窗口,触发FormClosing事件保存设置
/// </summary>
private void BarEXIT_ItemClick(object sender, ItemClickEventArgs e)
{
this.Close(); // 触发FormClosing事件,在事件中保存设置并清理资源
}
/// <summary>
/// 退出按钮点击事件(设计模式)
/// 在设计模式下退出时显式保存窗口设置
/// </summary>
private void BarExitSj_ItemClick(object sender, ItemClickEventArgs e)
{
SaveFmSet(); // 保存窗口设置
this.Close(); // 关闭窗口
}
/// <summary>
/// 分类目录功能定义按钮点击事件
/// 打开分类目录功能的定义界面
/// </summary>
private void BarFLML_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("分类目录");
}
/// <summary>
/// 关联输入功能定义按钮点击事件
/// 打开关联输入功能的定义界面
/// </summary>
private void BarGLSR_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("关联输入");
}
/// <summary>
/// 功能列表定义按钮点击事件
/// 打开功能列表管理界面,用于管理系统所有功能模块
/// </summary>
private void BarGNLB_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
// 检查功能列表定义窗口是否已经打开(避免重复打开)
foreach (Form opfm in Application.OpenForms)
{
if (opfm.Name == "gn01_flml")
{
if (opfm.Text == "功能列表定义")
{
// 如果已打开,则激活并前置该窗口
opfm.WindowState = FormWindowState.Normal;
opfm.Activate();
return; // 直接返回,不再创建新窗口
}
}
}
// 创建新的功能列表定义窗口
Uf01Flml gnform = new Uf01Flml
{
Text = "功能列表定义", // 窗口标题
fgnbh = "9982", // 功能编号
fgnmc = "功能列表定义", // 功能名称
ftlist = "gnbh,sj,bj,jc,gnmc,gnly,gnlb,ssmk,t1,t2,zdbb,sfyc,sfqy,sfql,sfsd", // 显示字段列表
ftbm = "gnbh", // 主键字段
ftsj = "sj", // 时间字段
ftbj = "bj", // 标记字段
ftmc = "gnmc", // 名称字段
ftone = "", // 单选框字段(空表示不使用)
ftml = "gnbh,gnmc,gnly,gnlb,ssmk,t1,t2,zdbb,sfyc,sfqy,sfql", // 模板字段
ftjc = "jc", // 简称字段
ftwhere = "1=1", // 查询条件(1=1表示查询所有)
ftorder = "gnbh", // 排序字段
ftqy = "sfsd", // 启用字段
ftfz = true, // 是否允许复制
ft1 = "x9_gn", // 主表名
ftbb = "", // 版本号(空表示无版本控制)
fxz = "11111111" // 权限控制字符串(8位二进制,每位代表一种操作权限)
};
gnform.Show(); // 以非模态方式显示窗口
}
catch (Exception ex)
{
MsgExShow("执行功能列表定义", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 帮助按钮点击事件(账套模式)
/// 打开帮助文档或帮助系统
/// </summary>
private void BarHELP_ItemClick(object sender, ItemClickEventArgs e)
{
RunHelpyy(this, pZTMC, pSFSJ); // 调用帮助系统
}
/// <summary>
/// 帮助按钮点击事件(设计模式)
/// 打开设计模式的帮助文档
/// </summary>
private void BarHELPSJ_ItemClick(object sender, ItemClickEventArgs e)
{
RunHelpsj(this, pZTMC); // 调用设计模式帮助
}
/// <summary>
/// 汇总查询功能定义按钮点击事件
/// 打开汇总查询功能的定义界面
/// </summary>
private void BarHZCX_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("汇总查询");
}
/// <summary>
/// 数据库重新连接按钮点击事件
/// 当数据库连接异常断开时,尝试重新连接数据库
/// </summary>
private void BarSJLJ_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
try
{
KcDb.SFlj = KcDb.DBLJ(); // 重新获取数据库连接字符串
}
catch (Exception ex)
{
MsgExShow("重新连接本地数据库", ex.Message, ex.Source, ex.StackTrace);
}
// 显示当前数据库连接状态
MsgXxShow("数据库连接目前处理于[" + Gethydbzt() + "]状态");
}
/// <summary>
/// 设置皮肤按钮点击事件
/// 打开皮肤选择窗口,允许用户更改界面主题
/// </summary>
private void BarSKIN_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
FmSKIN skfm = new FmSKIN(); // 创建皮肤设置窗口
skfm.ShowDialog(); // 以模态方式显示
skfm.Dispose(); // 释放窗口资源
}
/// <summary>
/// 文件下载按钮点击事件
/// 打开文件下载管理界面(需要系统管理员权限)
/// </summary>
private void BarWjxz_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
// 权限检查:只有系统管理员可以访问此功能
if (!pYHJS.Contains("系统管理员"))
{
MsgXxShow("该功能需要系统管理员权限!");
return; // 无权限,直接返回
}
FmWjxz fmwj = new FmWjxz(); // 创建文件下载窗口
fmwj.Show(); // 以非模态方式显示
}
/// <summary>
/// 用户密码修改按钮点击事件
/// 打开密码修改窗口,允许当前用户修改登录密码
/// </summary>
private void BarYHMM_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
FmYHMM fmm = new FmYHMM(); // 创建密码修改窗口
fmm.ShowDialog(this); // 以模态方式显示,this作为父窗口
}
/// <summary>
/// 用户信息查看按钮点击事件
/// 打开当前用户信息查看窗口
/// </summary>
private void BarYHXX_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
try
{
FmYhxx fyhxx = new FmYhxx(); // 创建用户信息窗口
fyhxx.ShowDialog(); // 以模态方式显示
}
catch (Exception ex)
{
MsgExShow("重新连接本地数据库", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 业务处理功能定义按钮点击事件
/// 打开业务处理功能的定义界面
/// </summary>
private void BarYWCL_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunGndy("业务处理");
}
/// <summary>
/// 重新启动按钮点击事件
/// 保存当前状态后重新启动应用程序(用于切换账套等场景)
/// </summary>
private void BarZTLJ_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
ReLogin(); // 调用重新登录方法
}
/// <summary>
/// 刷新任务列表按钮点击事件
/// 手动刷新右侧的"我的任务"列表,获取最新的待办任务
/// </summary>
private void Btrwmw_Click(object sender, EventArgs e)
{
Reloadrw(GridRW, rwgv); // 重新加载任务数据
}
/// <summary>
/// 自动配置列宽菜单项点击事件(从右键菜单调用)
/// 根据当前网格宽度自动调整所有可见列的宽度
/// </summary>
private void Dxmenuclick()
{
Gvoptionwithmin(ref rwgv, GridRW.Width); // 调用自动调整列宽的方法
}
/// <summary>
/// 手动配置列宽菜单项点击事件(从右键菜单调用)
/// 保存当前列宽设置为默认配置
/// </summary>
private void Dxsdclick()
{
Gvsdoption(ref rwgv); // 调用保存列宽配置的方法
}
/// <summary>
/// 窗口激活事件
/// 当窗口从后台切换到前台时触发,用于刷新任务列表
/// </summary>
private void Form_Activated(object sender, EventArgs e)
{
if (pquit) return; // 如果正在退出程序,直接返回
if (gnyx) // 如果功能正在运行
{
gnyx = false; // 重置标志
return;
}
Reloadrw(GridRW, rwgv); // 刷新任务列表,确保显示最新任务
if (this.WindowState != FormWindowState.Normal) return; // 如果窗口不是正常状态,返回
this.Focus(); // 获取焦点
}
/// <summary>
/// 窗口关闭事件
/// 在窗口关闭前保存所有设置并清理资源
/// </summary>
private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
// 保存窗口参数到XML文件
if (pFMSD == "否")
{
if (pDSFM != null)
{
try
{
pDSFM.WriteXml(cslj + pDBmc + "_" + myscreen + ".xml");
pDSFM.AcceptChanges(); // 标记为已保存
}
catch (Exception ex)
{
MsgExShow("提交窗口参数", ex.Message, ex.Source, ex.StackTrace);
}
}
}
// 关闭数据库连接
try
{
pquit = true; // 设置退出标志
KcDb.Dispose(); // 释放数据库资源
}
catch (Exception ex)
{
MsgExShow("关闭数据连接", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 窗口加载事件 - 系统初始化入口
/// 在窗口显示前执行所有初始化操作
/// 执行顺序:环境检查 → 数据库连接 → 权限加载 → 界面构建
/// </summary>
private void Form_Load(object sender, EventArgs e)
{
try
{
this.Visible = false; // 先隐藏窗口,避免初始化过程闪烁
// 1. 获取屏幕信息和设置窗口
pBJMC = System.Environment.MachineName; // 计算机名
pFMWX = Screen.PrimaryScreen.WorkingArea.Width; // 主屏幕工作区宽度
pFMWY = Screen.PrimaryScreen.WorkingArea.Height; // 主屏幕工作区高度
SetDg(this, 1680, 700, true); // 设置窗口默认大小和位置(1680x700,居中显示)
// 计算屏幕缩放比例(基于1920x1080基准分辨率)
double bzwt = 1920.0;
double pmwt = Convert.ToDouble(pFMWX);
pFMBL = pmwt / bzwt; // 缩放比例,用于自适应不同分辨率
// 设置分割器的默认位置
Sp1.SplitterPosition = 298;
// 生成屏幕分辨率标识字符串(如:1920_1080)
myscreen = Screen.PrimaryScreen.WorkingArea.Width.ToString().Trim() + "_" +
Screen.PrimaryScreen.WorkingArea.Height.ToString().Trim();
// 2. 设置状态栏日期显示
tsRQ.Caption = KcTool.GetYLDate(DateTime.Now.Date); // 格式化为中文日期
// 3. 获取PC唯一标识
pPCBH = GetId();
// 4. 设置Ribbon标题
RibbonControl.ApplicationDocumentCaption = "看潮企业管理软件";
RibbonControl.ApplicationCaption = "看潮企业管理软件";
// 5. 初始化配置目录
cslj = pAppPath + "FormCs"; // 配置存储路径
if (!System.IO.Directory.Exists(cslj))
{
System.IO.Directory.CreateDirectory(cslj);
}
// 创建图片存储子目录(分为三类图标)
if (!System.IO.Directory.Exists(cslj + "\\image1"))
{
System.IO.Directory.CreateDirectory(cslj + "\\image1");
}
if (!System.IO.Directory.Exists(cslj + "\\image2"))
{
System.IO.Directory.CreateDirectory(cslj + "\\image2");
}
if (!System.IO.Directory.Exists(cslj + "\\image3"))
{
System.IO.Directory.CreateDirectory(cslj + "\\image3");
}
// 6. 初始化文档目录
pDoc = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (!System.IO.Directory.Exists(pDataRoot))
{
System.IO.Directory.CreateDirectory(pDataRoot);
}
cslj = cslj + "\\"; // 确保路径以反斜杠结尾
}
catch (Exception ex)
{
MsgExShow("初始应用环境", ex.Message, ex.Source, ex.StackTrace);
}
// 7. 加载主程序
try
{
LoadForm(); // 核心初始化方法
}
catch (Exception ex)
{
MsgExShow("加载应用程序", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 网格自定义行单元格编辑器事件
/// 根据单元格值动态设置单元格的编辑器类型
/// 主要用于任务列表中的"执行"按钮列
/// </summary>
private void Gdgv_Customrowcelledit(object sender, DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs e)
{
try
{
// 只处理"rwexec"列(执行操作列)
if (e.Column.FieldName != "rwexec")
{
return;
}
// 获取单元格值
string cellValue = e.CellValue?.ToString().Trim() ?? "";
if (cellValue == "")
{
// 如果值为空,使用默认文本编辑器
e.RepositoryItem = rctt;
}
else
{
// 在按钮名称数组中查找对应的按钮
int i = Array.IndexOf(rcbtmc, cellValue);
if (i >= 0)
{
// 找到对应按钮,使用按钮编辑器
e.RepositoryItem = rcbt[i];
}
else
{
// 未找到,使用默认文本编辑器
e.RepositoryItem = rctt;
}
}
}
catch (Exception)
{
// 静默处理异常
}
}
/// <summary>
/// 获取数据库连接状态
/// 将System.Data.ConnectionState枚举转换为中文描述
/// </summary>
/// <returns>数据库连接状态的中文描述</returns>
private string Gethydbzt()
{
string zt = "未知";
switch (KcDb.KcCn.State)
{
case ConnectionState.Broken:
zt = "已经中断";
break;
case ConnectionState.Open:
zt = "已经打开";
break;
case ConnectionState.Closed:
zt = "已经关闭";
break;
case ConnectionState.Connecting:
zt = "正在连接";
break;
case ConnectionState.Executing:
zt = "正在执行命令";
break;
}
return zt;
}
/// <summary>
/// 获取展开模块设置
/// 读取布局控件中展开的分组,保存到设置中
/// </summary>
/// <param name="mklc">布局控件(如业务处理、信息查询、基础资料面板)</param>
private void GetZkMk(LayoutControl mklc)
{
try
{
string ywmk = ""; // 用于存储展开模块的字符串
LayoutControlGroup lc;
// 遍历布局控件的根项
for (int l = 0; l < mklc.Root.Items.Count; l++)
{
if (mklc.Root.Items[l].IsGroup) // 如果是分组
{
lc = (LayoutControlGroup)mklc.Root.Items[l];
if (lc != null)
{
if (lc.Expanded) // 如果分组是展开状态
{
if (ywmk == "")
{
ywmk = lc.Text; // 第一个模块
}
else
{
ywmk += "`" + lc.Text; // 用`分隔多个模块
}
}
}
}
}
// 保存到设置中
FmSave(mklc.Name + "展开模块", ywmk);
}
catch (Exception)
{
// 静默处理异常
}
}
/// <summary>
/// 任务链接按钮点击事件
/// 处理任务列表中的操作按钮点击,执行相应的任务处理功能
/// 设计特点:基于工作流引擎的任务驱动处理
/// </summary>
private void Ljcx_Buttonclick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
{
try
{
string ljgnmc = e.Button.Caption; // 获取按钮文本(功能名称)
// 从当前行获取任务相关参数
object ljrwlbObj = rwgv.GetRowCellValue(rwgv.FocusedRowHandle, rwgv.Columns["rwly"]);
string ljrwlb = ljrwlbObj != null ? ljrwlbObj.ToString() : ""; // 任务来源
object ljrwxhObj = rwgv.GetRowCellValue(rwgv.FocusedRowHandle, rwgv.Columns["rwbh"]);
string ljrwxh = ljrwxhObj != null ? ljrwxhObj.ToString() : ""; // 任务编号
object ljrwidObj = rwgv.GetRowCellValue(rwgv.FocusedRowHandle, rwgv.Columns["rwid"]);
string ljrwid = ljrwidObj != null ? ljrwidObj.ToString() : ""; // 任务ID
object ljbpidObj = rwgv.GetRowCellValue(rwgv.FocusedRowHandle, rwgv.Columns["bpid"]);
string ljbpid = ljbpidObj != null ? ljbpidObj.ToString() : ""; // 流程实例ID
object ljsqryObj = rwgv.GetRowCellValue(rwgv.FocusedRowHandle, rwgv.Columns["sqry"]);
string ljsqry = ljsqryObj != null ? ljsqryObj.ToString() : ""; // 申请人员
// 权限验证:当前用户是否在申请人员列表中
if (!ljsqry.Contains(pDQYH))
{
return; // 无权限,直接返回
}
// 从权限表中查找该功能
DataRow[] dr = pDTQX.Select("gnmc='" + ljgnmc + "'");
if (dr.Length > 0)
{
string fl = dr[0]["gnly"].ToString(); // 功能类别
string bh = dr[0]["gnbh"].ToString(); // 功能编号
string xz = dr[0]["xzqx"].ToString(); // 执行权限
// 特定类别功能需要传递流程实例ID(bpid)
if ((fl == "单据输入" || fl == "单据审批" || fl == "单据查询" || fl == "工资计件") && ljbpid != "")
{
// 调用功能执行方法,传递流程实例ID
X9gn(ljgnmc, fl, bh, xz, null, ljbpid);
}
else
{
// 普通功能执行
X9gn(ljgnmc, fl, bh, xz, null, null);
}
}
else
{
MsgOxShow("当前操作员无此权限"); // 显示无权限提示
}
KcDb.DBclose(); // 关闭数据库连接
}
catch (Exception ex)
{
MsgExShow("执行链接任务", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 主初始化方法:完成所有启动时必要的加载
/// 这是系统的核心初始化流程,调用链中的关键方法
/// </summary>
private void LoadForm()
{
this.Text = ""; // 清空窗口标题
// 1. 显示启动进度窗口
FmSp fgy = new FmSp(); // 启动画面/进度窗口
fgy.Show(this);
// 2. 创建数据目录结构
pDataPath = pDataRoot + "\\" + pDBmc; // 数据库专用数据路径
if (!System.IO.Directory.Exists(pDataPath))
{
System.IO.Directory.CreateDirectory(pDataPath);
}
// 备份目录
pBak = pDataPath + "\\bak";
if (!System.IO.Directory.Exists(pBak))
{
System.IO.Directory.CreateDirectory(pBak);
}
// 日志目录
pFilesLog = pDataPath + "\\log";
if (!System.IO.Directory.Exists(pFilesLog))
{
System.IO.Directory.CreateDirectory(pFilesLog);
}
// 文件存储目录
pFilesLC = pDataPath + "\\files";
if (!System.IO.Directory.Exists(pFilesLC))
{
System.IO.Directory.CreateDirectory(pFilesLC);
}
// 临时文件目录
pFilesTemp = pDataPath + "\\temp";
if (!System.IO.Directory.Exists(pFilesTemp))
{
System.IO.Directory.CreateDirectory(pFilesTemp);
}
// 报表目录
pFilesReport = pDataPath + "\\rpt";
if (!System.IO.Directory.Exists(pFilesReport))
{
System.IO.Directory.CreateDirectory(pFilesReport);
}
// 查询文件目录
pFilesQuery = pDataPath + "\\query";
if (!System.IO.Directory.Exists(pFilesQuery))
{
System.IO.Directory.CreateDirectory(pFilesQuery);
}
// XML文件目录
pFilesXml = pDataPath + "\\xml";
if (!System.IO.Directory.Exists(pFilesXml))
{
System.IO.Directory.CreateDirectory(pFilesXml);
}
// 3. 设置软件标题
pZTMC = "看潮企业管理软件";
fgy.LZTMC.Text = pZTMC;
fgy.Refresh();
RibbonControl.ApplicationCaption = pZTMC;
string pcinfo = "";
try
{
// 4. 记录PC信息并获取用户权限
pcinfo = GetPc(); // 获取PC硬件信息
// 记录PC使用信息到数据库
string exesql = "select x9_pcxh('" + pPCBH + "','" + pBJMC + " " + pRJBB + "','" + pDQYH + "','" + pcinfo + "')";
pPCXH = KcDb.DBexec(exesql); // 执行存储过程,返回PC序号
// 获取用户信息
pYHXH = KcDb.DBString("select yhbh from x9_gnyh where yhmc='" + pDQYH + "'"); // 用户编号
pDQBM = KcDb.DBString("select yhbm from x9_gnyh where yhmc='" + pDQYH + "'"); // 用户部门
// 5. 加载账套参数
pDTCS = KcDb.DtRead("select id,cslx, csmc, szjg, zfjg, ljjg from x9_ztcs"); // 读取账套参数表
// 获取常用参数
pSYDW = GetZfcs("使用单位", ""); // 使用单位名称
pMCSX = GetZfcs("单位名称缩写", ""); // 单位简称
pDWYJ = GetZfcs("单位邮件地址", ""); // 单位邮箱
pCPDH = GetZfcs("授权产品代号", "1201"); // 产品代号
pZSBH = GetZfcs("授权证书编号", ""); // 证书编号
// 重新设置软件标题(确保显示正确的账套名称)
pZTMC = "看潮企业管理软件";
fgy.LZTMC.Text = pZTMC;
fgy.Refresh();
RibbonControl.ApplicationCaption = pZTMC;
// 6. 加载本地配置参数
pSBGS = GetLjcs("鼠标跟随", false); // 鼠标跟随功能
pSBZY = GetLjcs("鼠标跟随定位窗体中央", false); // 鼠标定位到窗体中央
pGDRQ = GetLjcs("使用手动业务日期", false); // 是否使用手动业务日期
pCSGS = GetLjcs("测试计算公式", false); // 计算公式测试
pZDHH = GetLjcs("单据自动行号", true); // 自动行号
pCXCX = GetLjcs("重新查询", true); // 重新查询
pDWDZ = GetZfcs("单位地址", ""); // 单位地址
pDWLX = GetZfcs("单位联系方式", ""); // 单位联系方式
pMaxWt = GetSzcs("表格配置最大列宽", 120); // 表格最大列宽
pMinWt = GetSzcs("表格配置最小列宽", 50); // 表格最小列宽
}
catch (Exception ex)
{
// 静默处理参数加载异常
}
try
{
// 7. 加载文件关联设置
if (Directory.Exists(pAppPath + "sdfilesseting.xml"))
{
pGLWJ.ReadXml(pAppPath + "sdfilesseting.xml"); // 读取XML配置文件
}
}
catch (Exception ex)
{
fgy.Dispose();
pGLWJ = null;
MsgExShow("加载文件关联应用程序文件sdfilesseting.xml", ex.Message, ex.Source, ex.StackTrace);
}
try
{
// 8. 加载窗口参数数据集
pDSFM = new DataSet();
if (File.Exists(cslj + pDBmc + "_" + myscreen + ".xml"))
{
// 如果存在保存的窗口参数文件,读取它
pDSFM.ReadXml(cslj + pDBmc + "_" + myscreen + ".xml");
pDSFM.AcceptChanges(); // 标记为未修改
}
else
{
// 否则创建空的参数表
pDSFM.Tables.Add(Makefmdt());
}
}
catch (Exception ex)
{
fgy.Dispose();
MsgExShow("加载窗口参数文件formset" + pDBmc + pDLmc + ".xml", ex.Message, ex.Source, ex.StackTrace);
}
try
{
// 9. 设置默认选中的Ribbon页
RibbonControl.SelectedPage = RibbonControl.Pages[0];
fgy.Refresh();
// 更新进度显示
fgy.JD.Text = "...正在打开数据库[" + pDBmc + "]...";
fgy.jdleft();
fgy.Refresh();
// 根据是否为设计模式显示不同的Ribbon页
if (pSFSJ) // 设计模式
{
RibbonControl.SelectedPage = RibbonPageSJ;
RibbonPageSJ.Visible = true;
}
else // 运行模式
{
RibbonControl.SelectedPage = RibbonPageZT;
RibbonPageSJ.Visible = false;
}
// 10. 加载菜单图片
fgy.JD.Text = "...正在加载菜单图片...";
fgy.jdleft();
fgy.Refresh();
// 定义需要加载图片的菜单项名称
string[] cdname;
string fmgnmc = "载入,提交,帮助,返回,预览,打印,确定,取消,删除,添加同级,添加下级,展开,收起,查找"; // 基础功能
fmgnmc += ",公式重算,标记或取消审核,布局方向切换,文件导出,文件导入"; // 数据处理功能
fmgnmc += ",调入,添加,修改,键盘,作废,审核,登记"; // 单据操作功能
fmgnmc += ",流转,回退,全部流转,全部回退"; // 工作流功能
fmgnmc += ",编辑,验证,全部审核,全部登记,部分审核,部分登记,连续预览,连续打印"; // 审批功能
fmgnmc += ",执行,连接,暂存,编码转换,文件下载,升级工具,设计文件"; // 系统工具
fmgnmc += ",列赋值,列清空,列替换,设计字典,系统字典,功能字典"; // 数据字典
fmgnmc += ",重新启动,重新连接,用户密码,用户信息,运行,迁移,版权信息,设置皮肤,退出"; // 主窗口功能
fmgnmc += ",功能列表,分类目录,查询输入,关联输入,单据输入,单据审批,业务处理,单据查询,汇总查询"; // 设计功能
fmgnmc += ",复制功能定义,复制计算公式,复制输入限制,导入功能定义,当前功能运行测试,多选模式"; // 高级功能
// 设置图片目录
pTBZD = "image" + pCDTB; // 如:image1、image2、image3
string tname = "";
Image newimage = null;
pCdimage.ImageSize = new Size(32, 32); // 设置图标大小
// 分割菜单项名称
cdname = fmgnmc.Split(',');
for (int r = 0; r < cdname.Length; r++)
{
if (cdname[r].Trim() != "")
{
tname = cdname[r].ToString().Trim() + ".png"; // 图片文件名
if (File.Exists(cslj + "\\" + pTBZD + "\\CD" + tname))
{
// 加载图片到图像集合
newimage = Image.FromFile(cslj + "\\" + pTBZD + "\\CD" + tname);
pCdimage.Images.Add(newimage, cdname[r].ToString().Trim());
}
}
}
// 将图片应用到Ribbon按钮
if (pCdimage.Images.Count > 0)
{
foreach (BarItem item in RibbonControl.Items)
{
if (item.GetType().Name.ToLower() == "barbuttonitem") // 只处理按钮项
{
if (pCdimage.Images.Keys.IndexOf(item.Caption) >= 0)
{
item.LargeGlyph = pCdimage.Images[item.Caption]; // 设置大图标
}
}
}
}
// 11. 加载功能模块图标
fgy.JD.Text = "...正在加载功能图片...";
fgy.jdleft();
fgy.Refresh();
// 从数据库读取功能模块列表
dtgntp = KcDb.DtRead("select mkmc from x9_gn_gnmk");
int tprows = dtgntp.Rows.Count - 1;
gnimage.ImageSize = new Size(32, 32); // 功能图标大小
string wjex = ""; // 记录找不到的图片文件
for (int i = 0; i <= tprows; i++)
{
try
{
tname = dtgntp.Rows[i]["mkmc"].ToString() + ".png"; // 模块图片文件名
if (File.Exists(cslj + "\\" + pTBZD + "\\MK" + tname))
{
newimage = System.Drawing.Image.FromFile(cslj + "\\" + pTBZD + "\\MK" + tname);
gnimage.Images.Add(newimage, dtgntp.Rows[i]["mkmc"].ToString());
}
}
catch (Exception ex)
{
wjex += tname + "\r\n"; // 记录错误文件名
}
}
// 如果有找不到的图片,记录到日志文件
if (wjex != "")
{
CreateTextFile(pFilesLog + "\\没有找到文件的图标" + DateTime.Now.ToString("yyyyMMddhhsstt") + ".txt", wjex);
}
wjex = null;
// 12. 加载用户权限
pDTQX = null;
pYHJS = KcDb.DBString("select yhjs from x9_gnyh where yhmc='" + pDQYH + "'"); // 用户角色
string gnsql = "";
if (sqmk == "")
{
// 默认授权模块(如果未特别指定)
sqmk = "'分类目录','基础设置','系统维护','系统设计','文件资料管理','人事档案管理'";
}
// 构建权限查询SQL:联合用户权限表和功能模块表
gnsql = "select qx.gnbh, qx.gnmc, qx.gnly, qx.gnlb, qx.ssmk, min(qx.jzzd) as jzzd, max(qx.xzqx) as xzqx, mk.mkxh, qx.sfyc,qx.zjm " +
" from x9_gnyhqx as qx inner join x9_gn_gnmk as mk on qx.ssmk = mk.mkmc and mk.sfyy=true " +
" where position(qx.yhjs in '" + pYHJS + "') > 0 and (qx.sfsq = true) " +
" group by qx.gnbh, qx.gnmc, qx.gnly, qx.gnlb, qx.ssmk,mk.mkxh,qx.sfyc,qx.zjm " +
" order by mk.mkxh, qx.gnbh";
pDTQX = KcDb.DtRead(gnsql); // 执行查询,获取用户有权限的功能列表
// 13. 读取账套选项和参数
fgy.JD.Text = "...正在读取账套选项和参数...";
fgy.jdleft();
fgy.Refresh();
// 获取表格行高参数
PanelRowHeight = GetSzcs("表格标题高度", 36);
if (pDTCS.DataSet.HasChanges())
{
// 如果有参数更改,保存到数据库
KcDb.GetDtSaven("x9_ztcs", pDTCS.GetChanges());
pDTCS.AcceptChanges();
}
if (PanelRowHeight < 28) PanelRowHeight = 28; // 最小行高限制
PanelRowHeightJj = GetSzcs("计件工作量标题高度", 36); // 计件表格行高
if (PanelRowHeightJj < 28) PanelRowHeightJj = 28;
// 自动调整参数范围检查
if (pAUTO < 10 || pAUTO > 36) pAUTO = 10;
// 14. 设置业务期间和日期
pQYQJ = KcDb.DBString("select min(ny) as ny from mlny"); // 最早业务期间
pYWQJ = KcDb.DBString("select max(ny) as ny from mlny"); // 当前业务期间
pYWRQ = Convert.ToDateTime(GetZfcs("手动业务日期",
pYWQJ.Substring(0, 4) + "-" + pYWQJ.Substring(4, 2) + "-" + "01")); // 默认设为期间第一天
Tsywrq.EditValue = pYWRQ; // 更新界面控件
// 15. 更新状态栏信息
ts1.Caption = "[账套用户:" + pDQYH + " " + pYHJS + "]"; // 用户信息
ts3.Caption = "[业务期间:" + pYWQJ + "]"; // 业务期间
LcYxZt.Text = "[" + pSYDW + "]" + "[" + pZTMC + "]" + "[" + pDBmc + "]" +
(pSFSJ ? "[设计]" : "[运行]"); // 运行状态
RibbonControl.ApplicationDocumentCaption = pSYDW; // 文档标题
RibbonControl.ApplicationCaption = pZTMC; // 应用程序标题
// 16. 动态加载三个主要功能面板
// 基础资料面板
DataRow[] dr = pDTQX.Select("(gnlb='基础资料') and sfyc=false", "mkxh,gnbh");
MyGn("基础资料", dr, PgJC, jclc);
// 信息查询面板
dr = pDTQX.Select("(gnlb='信息查询') and sfyc=false", "mkxh,gnbh");
MyGn("信息查询", dr, PGxx, xxlc);
// 业务处理面板
dr = pDTQX.Select("gnlb='业务处理' and sfyc=false", "mkxh,gnbh");
MyGn("业务处理", dr, PGyw, ywlc);
}
catch (Exception ex)
{
fgy.Dispose();
MsgExShow("装入程序菜单", ex.Message, ex.Source, ex.StackTrace);
return;
}
try
{
// 17. 保存账套参数更改(如果有)
if (pDTCS.DataSet.HasChanges())
{
KcDb.GetDtSaven("x9_ztcs", pDTCS.GetChanges());
pDTCS.AcceptChanges();
}
}
catch (Exception ex)
{
MsgExShow("保存账套参数", ex.Message, ex.Source, ex.StackTrace);
}
try
{
// 18. 加载打印机列表
string pkinstalledprinters;
string pddefaultprinter;
PrintDocument printdoc = new PrintDocument();
pddefaultprinter = printdoc.PrinterSettings.PrinterName; // 默认打印机
// 遍历系统安装的所有打印机
for (int i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)
{
pkinstalledprinters = PrinterSettings.InstalledPrinters[i];
printdoc.PrinterSettings.PrinterName = pkinstalledprinters;
if (printdoc.PrinterSettings.IsValid) // 检查打印机是否有效
{
RcPt1.Items.Add(pkinstalledprinters); // 添加到下拉列表
}
}
// 设置默认打印机
BarDqpt.EditValue = pddefaultprinter;
pPrinterName = pddefaultprinter;
}
catch (Exception ex)
{
MsgExShow("加载打印机列表", ex.Message, ex.Source, ex.StackTrace);
}
try
{
// 19. 加载任务列表
LoadRwgv(GridRW, rwgv);
}
catch (Exception ex)
{
fgy.Dispose();
this.Refresh();
MsgExShow("加载我的任务表格视图", ex.Message, ex.Source, ex.StackTrace);
}
// 20. 检查是否为技术服务人员
if (ts5.Caption.Contains("[技术服务人员]"))
{
pWHRY = true; // 设置技术服务人员标志
}
// 21. 读取屏幕参数
fgy.JD.Text = "...正在读取屏幕参数...";
fgy.jdleft();
fgy.Refresh();
fgy.Dispose(); // 关闭启动进度窗口
try
{
// 22. 应用保存的窗口设置
string fmset = FmRead("主窗口");
string[] fmay = fmset.Split(',');
if (fmay.Length >= 7)
{
Int16 ws = 0;
if (fmay.Length == 7)
{
ws = Convert.ToInt16(fmay[6]); // 窗口状态(0正常,1最小化,2最大化)
if (ws == 2)
{
this.WindowState = FormWindowState.Maximized; // 最大化窗口
}
}
if (ws == 0) // 正常状态
{
if (Convert.ToInt32(fmay[0]) > 0) this.Top = Convert.ToInt32(fmay[0]); // 顶部位置
if (Convert.ToInt32(fmay[1]) > 0) this.Left = Convert.ToInt32(fmay[1]); // 左侧位置
if (Convert.ToInt32(fmay[2]) > 800) this.Width = Convert.ToInt32(fmay[2]); // 宽度
if (Convert.ToInt32(fmay[3]) > 500) this.Height = Convert.ToInt32(fmay[3]); // 高度
}
if (Convert.ToInt32(fmay[4]) > 50) Sp1.SplitterPosition = Convert.ToInt32(fmay[4]); // 分割器位置
GNTab.SelectedTabPageIndex = Convert.ToInt32(fmay[5]); // 选中的标签页索引
}
}
catch (Exception ex)
{
fgy.Dispose();
MsgExShow("应用窗口参数", ex.Message, ex.Source, ex.StackTrace);
}
this.Refresh();
this.Visible = true; // 显示主窗口
try
{
// 23. 安全检查:提示设置密码(如果用户没有密码)
if (KcDb.DBString("select yhmm from x9_gnyh where yhmc='" + pDQYH + "'") == "")
{
MsgXxShow("为保证您的安全使用,请设置您的登录密码");
FmYHMM fmm = new FmYHMM();
fmm.ShowDialog(this); // 强制用户设置密码
}
}
catch (Exception ex)
{
MsgExShow("打开用户密码设置窗口", ex.Message, ex.Source, ex.StackTrace);
}
try
{
// 24. 验证业务期间与业务日期的一致性
if (pYWQJ != pYWRQ.ToString("yyyyMM"))
{
MsgXxShow("当前业务期间与业务日期不一致,请谨慎操作。请系统管理员在月末时及时完成月末处理!");
}
}
catch (Exception ex)
{
MsgExShow("验证业务期间与业务日期的一致性", ex.Message, ex.Source, ex.StackTrace);
}
try
{
// 25. 设计模式下清理异常日志
if (pSFSJ) // 如果是设计模式
{
int yxzt = 0; // 运行状态记录数
int qdcw = 0; // 客户端错误数
int hdcw = 0; // 服务端错误数
int sqljl = 0; // SQL记录数
// 统计各种异常记录
yxzt = KcDb.DBInteger("select count(*) from x9_yxzt");
sqljl = KcDb.DBInteger("select count(*) from x9_jlsql");
hdcw = KcDb.DBInteger("select count(*) from x9_errproc");
qdcw = KcDb.DBInteger("select count(*) from x9_errcode");
// 如果有异常记录,提示用户是否清理
if ((yxzt + qdcw + hdcw + sqljl) > 0)
{
if (MsgSfShow(" 运行状态数: " + yxzt.ToString().Trim() + "\r\n 数据访问数: " + sqljl.ToString().Trim() + "\r\n" +
" 服务端异常: " + hdcw.ToString().Trim() + "\r\n 客户端异常: " + qdcw.ToString().Trim() + "\r\n\r\n" +
"是否直接删除这些记录?") == DialogResult.OK)
{
// 用户确认,清理所有异常记录
KcDb.DBexec("delete from x9_yxzt");
KcDb.DBexec("delete from x9_errcode");
KcDb.DBexec("delete from x9_errproc");
KcDb.DBexec("delete from x9_jlsql");
}
}
}
KcDb.DBclose(); // 关闭数据库连接
}
catch (Exception ex)
{
MsgExShow("系统异常日志提示", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 加载任务列表到网格视图
/// 从数据库读取当前用户的任务,并动态配置网格列
/// </summary>
/// <param name="gd">网格控件</param>
/// <param name="gv">网格视图</param>
private void LoadRwgv(GridControl gd, GridView gv)
{
try
{
DataTable dt = new DataTable();
string rwsql;
// 设置任务标题
Trwdb.Text = "[" + pYHJS + "][" + pDQYH + "]工作任务 ";
// 构建任务查询SQL:查询当前用户相关的任务
rwsql = "select rwid,djmc,bpid,rwbh,rwmc,zrry,sqry,wcsj,wcry,rwzy,rwexec,sfwc " +
"from x9_bprw where (position('" + pDQYH + "'in sqry)>0 or position('系统管理员' in '" + pYHJS +
"') > 0 or sqry='') order by sfwc,rwid desc limit 300"; // 最多300条记录
dt = KcDb.DtRead(rwsql); // 执行查询
// 清空现有视图集合
gd.ViewCollection.Clear();
gv = new GridView(gd); // 创建新的网格视图
gv.BeginUpdate(); // 开始批量更新,提高性能
gv.Name = "rwgv";
gv.OptionsBehavior.AutoPopulateColumns = false; // 手动配置列
gd.DataSource = dt; // 设置数据源
gd.ForceInitialize(); // 强制初始化
gd.MainView = gv; // 设置主视图
gv.PopulateColumns(dt); // 根据数据表结构创建列
SetGv(ref gv, true); // 设置网格基本属性
gv.OptionsView.ShowFooter = false; // 不显示页脚
gv.OptionsBehavior.AutoUpdateTotalSummary = false; // 不自动更新汇总
gv.OptionsSelection.MultiSelect = true; // 允许多选
gv.OptionsSelection.MultiSelectMode = GridMultiSelectMode.RowSelect; // 行选择模式
gv.OptionsView.EnableAppearanceEvenRow = true; // 启用交替行背景色
gv.OptionsView.EnableAppearanceOddRow = true;
// 读取任务表的列定义(数据字典)
string zdsql = "select * from x9_sjzd where zdbb='' and tname='x9_bprw' and fmemo<>'' order by fxh";
DataTable dtzd = new DataTable();
dtzd = KcDb.DtRead(zdsql);
// 绑定右键菜单事件
gv.PopupMenuShowing += new DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventHandler(this.Mtgv_PopupMenuShowing);
if (dtzd != null && dtzd.Rows.Count > 0)
{
// 根据数据字典配置网格列
Gdlomyrw(ref gd, ref gv, ref dtzd);
gv.OptionsBehavior.ReadOnly = true; // 设置为只读
// 收集所有不同的操作按钮名称
string btmc = "";
string dqmc = "";
for (int r = 0; r < gv.RowCount; r++)
{
object cv = gv.GetRowCellValue(r, gv.Columns["rwexec"]);
if (cv != null)
{
dqmc = "[" + cv.ToString().Trim() + "]"; // 用方括号包裹
}
if (dqmc != "" && !btmc.Contains(dqmc))
{
btmc += dqmc + ","; // 用逗号分隔
}
}
// 如果有操作按钮,创建对应的编辑器
if (btmc != "")
{
// 处理按钮名称数组
rcbtmc = btmc.Substring(0, btmc.Length - 1).Split(','); // 去掉最后一个逗号并分割
rcbt = new RepositoryItemButtonEdit[rcbtmc.Length];
// 去掉方括号
for (int i = 0; i < rcbtmc.Length; i++)
{
rcbtmc[i] = rcbtmc[i].Substring(1, rcbtmc[i].Length - 2);
}
// 创建按钮编辑器
for (int i = 0; i < rcbtmc.Length; i++)
{
if (rcbtmc[i] != "")
{
RepositoryItemButtonEdit rc = new RepositoryItemButtonEdit
{
TextEditStyle = TextEditStyles.HideTextEditor // 隐藏文本编辑器,只显示按钮
};
rc.Buttons.Clear();
// 创建按钮
DevExpress.XtraEditors.Controls.EditorButton bt1 = new DevExpress.XtraEditors.Controls.EditorButton
{
Caption = rcbtmc[i], // 按钮文本
Kind = ButtonPredefines.Glyph // 按钮类型
};
rc.Buttons.Add(bt1);
rcbt[i] = rc;
gd.RepositoryItems.Add(rcbt[i]); // 添加到网格编辑器集合
rcbt[i].ButtonClick += Ljcx_Buttonclick; // 绑定按钮点击事件
}
}
// 绑定自定义单元格编辑器事件
gv.CustomRowCellEdit += Gdgv_Customrowcelledit;
}
}
gv.EndUpdate(); // 结束批量更新
gd.Tag = "gvend"; // 设置标记,表示网格已初始化完成
gd.UseEmbeddedNavigator = false; // 不使用内置导航器
// 隐藏不需要显示的列
gv.Columns["rwbh"].Visible = false; // 任务编号
gv.Columns["rwmc"].Visible = false; // 任务名称
gv.Columns["sqry"].Visible = false; // 申请人员
gd.Visible = true; // 显示网格
// 应用保存的列宽和行高设置
string fmset = FmRead("任务表格列宽行高");
string[] fmay = fmset.Split(',');
if (fmay.Length == gv.VisibleColumns.Count + 1) // 列宽数+行高
{
for (int c = 0; c < gv.VisibleColumns.Count; c++)
{
gv.VisibleColumns[c].Width = Convert.ToInt32(fmay[c]); // 设置列宽
}
if (Convert.ToInt32(fmay[fmay.Length - 1]) > 10)
{
gv.RowHeight = Convert.ToInt32(fmay[fmay.Length - 1]); // 设置行高
}
}
else
{
// 如果没有保存的设置,自动配置列宽
Gvoptionwithmin(ref gv, gd.Width);
}
}
catch (Exception ex)
{
MsgExShow("加载任务列表", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 网格右键菜单显示事件
/// 在网格的右键菜单中添加自定义菜单项
/// </summary>
private void Mtgv_PopupMenuShowing(object sender, DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventArgs e)
{
try
{
bool ists = false;
// 检查是否已经添加了自定义菜单项
foreach (DXMenuItem mi in e.Menu.Items)
{
if (mi.Caption == "自动配置列宽")
{
ists = true;
break;
}
}
// 如果没有添加,添加自定义菜单项
if (!ists)
{
// 添加"自动配置列宽"菜单项
DXMenuItem dxmenu = new DXMenuItem();
dxmenu.Caption = "自动配置列宽";
dxmenu.Click += (s, args) => Dxmenuclick(); // 绑定点击事件
e.Menu.Items.Add(dxmenu);
// 添加"手动配置列宽"菜单项
DXMenuItem dxmenusd = new DXMenuItem();
dxmenusd.Caption = "手动配置列宽";
dxmenusd.Click += (s, args) => Dxsdclick(); // 绑定点击事件
e.Menu.Items.Add(dxmenusd);
}
}
catch (Exception ex)
{
MsgExShow("增加配置列宽右键菜单", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 加载功能菜单的核心方法
/// 根据用户权限动态生成左侧导航面板(基础资料/信息查询/业务处理)
/// 设计模式:基于角色权限过滤 + 按模块分组展示 + 图标支持
/// </summary>
/// <param name="gnlb">功能类别:基础资料/信息查询/业务处理</param>
/// <param name="dr">功能数据行数组(已按权限过滤)</param>
/// <param name="pg">XtraTabPage标签页控件</param>
/// <param name="gnlc">LayoutControl布局控件</param>
private void MyGn(string gnlb, DataRow[] dr, XtraTabPage pg, LayoutControl gnlc)
{
try
{
// 1. 初始化布局控件
gnlc.Name = gnlb;
pg.Controls.Clear(); // 清空标签页原有控件
pg.Controls.Add(gnlc); // 添加布局控件到标签页
gnlc.Dock = DockStyle.Fill; // 填充整个标签页
// 2. 配置布局控件属性
gnlc.OptionsCustomizationForm.ShowLoadButton = false; // 不显示加载按钮
gnlc.OptionsCustomizationForm.ShowSaveButton = false; // 不显示保存按钮
gnlc.OptionsCustomizationForm.AllowHandleDeleteKey = true; // 允许删除键
gnlc.OptionsCustomizationForm.ShowPropertyGrid = true; // 显示属性网格
gnlc.AllowCustomization = false; // 不允许用户自定义布局
// 3. 从保存的设置中读取哪些模块是展开的
string mkset = FmRead(gnlb + "展开模块");
string[] mkay = mkset.Split('`'); // 使用`作为分隔符
gnlc.BeginUpdate(); // 开始批量更新,提高性能
gnlc.Root.Clear(); // 清空根节点
// 4. 如果有功能数据,动态生成功能菜单
if (dr.Length > 0)
{
int i = -1;
string gnssmk = ""; // 当前模块名称,用于检测模块变化
LayoutControlGroup dqgp = new LayoutControlGroup(); // 当前分组控件
// 遍历所有功能数据行
for (int j = 0; j < dr.Length; j++)
{
i++;
// 5. 检测模块变化:如果遇到新模块,创建新的分组
if (dr[j]["ssmk"].ToString() != gnssmk)
{
dqgp = new LayoutControlGroup();
dqgp.Name = "ktxx" + i.ToString("000"); // 生成唯一名称
dqgp.Text = dr[j]["ssmk"].ToString(); // 模块名称作为分组标题
dqgp.AllowHide = true; // 允许隐藏
dqgp.TextSize = new Size(100, 28); // 标题大小
dqgp.TextVisible = true; // 显示标题
dqgp.ExpandButtonVisible = true; // 显示展开/收起按钮
dqgp.ExpandOnDoubleClick = true; // 双击展开/收起
dqgp.HeaderButtonsLocation = GroupElementLocation.AfterText; // 按钮位置
dqgp.GroupBordersVisible = true; // 显示分组边框
dqgp.AllowCustomizeChildren = false; // 不允许自定义子项
dqgp.Expanded = false; // 默认收起
// 根据保存的设置决定分组是否展开
if (Array.IndexOf(mkay, dqgp.Text) > -1)
{
dqgp.Expanded = true; // 如果是之前展开的模块,保持展开状态
}
gnlc.AddGroup(dqgp); // 将分组添加到布局控件
}
// 6. 为每个功能创建一个按钮项
LayoutControlItem litem = new LayoutControlItem
{
FillControlToClientArea = false // 不填充客户区
};
// 创建功能按钮
SimpleButton xc = new SimpleButton
{
Name = "txx" + i.ToString("000"), // 唯一名称
Text = dr[j]["gnmc"].ToString() // 功能名称
};
xc.Cursor = Cursors.Hand; // 手型光标
// 设置功能图标(从ImageCollection中获取)
if (gnimage.Images.Keys.IndexOf(dr[j]["ssmk"].ToString()) >= 0)
{
xc.Image = gnimage.Images[dr[j]["ssmk"].ToString()];
}
// 在Tag中存储功能执行的必要参数(逗号分隔)
// 格式:功能名称,功能来源,功能编号,执行权限,功能类别
xc.Tag = dr[j]["gnmc"].ToString().Trim() + "," +
dr[j]["gnly"].ToString().Trim() + "," +
dr[j]["gnbh"].ToString().Trim() + "," +
dr[j]["xzqx"] + "," + gnlb;
xc.Enabled = true; // 启用按钮
xc.Click += RunGncd; // 绑定点击事件
xc.MinimumSize = new Size(100, 28); // 最小尺寸
litem.Name = "ixx" + i.ToString("000");
litem.Control = xc; // 设置按钮控件
litem.MinSize = new Size(100, 28); // 最小尺寸
litem.Text = dr[j]["gnmc"].ToString(); // 与按钮文本相同
litem.Tag = xc.Tag; // 复制Tag
litem.TextVisible = false; // 不显示文本(按钮上已有文本)
dqgp.AddItem(litem); // 将按钮项添加到当前分组
gnssmk = dr[j]["ssmk"].ToString(); // 更新当前模块
}
gnlc.BestFit(); // 自动调整布局
pg.PageVisible = true; // 如果有功能,显示该标签页
}
else
{
pg.PageVisible = false; // 无功能,隐藏标签页
}
gnlc.Tag = gnlb; // 在Tag中存储功能类别
gnlc.EndUpdate(); // 结束批量更新
}
catch (Exception ex)
{
MsgExShow("加载" + gnlb + "功能菜单", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 重新加载任务列表
/// 刷新右侧的"我的任务"列表,获取最新的待办任务
/// </summary>
/// <param name="gd">网格控件</param>
/// <param name="gv">网格视图</param>
private void Reloadrw(GridControl gd, GridView gv)
{
try
{
KcDb.DBopen(); // 打开数据库连接
DataTable dt = new DataTable();
string rwsql;
// 更新任务标题
Trwdb.Text = "[" + pYHJS + "][" + pDQYH + "]工作任务 ";
// 构建任务查询SQL(与LoadRwgv相同)
rwsql = "select rwid,djmc,bpid,rwbh,rwmc,zrry,sqry,wcsj,wcry,rwzy,rwexec,sfwc " +
"from x9_bprw where (position('" + pDQYH + "' in sqry)>0 or position('系统管理员' in '" + pYHJS +
"') > 0 or sqry='') order by sfwc,rwid desc limit 300";
dt = KcDb.DtRead(rwsql); // 执行查询
gd.DataSource = dt; // 重新绑定数据源
gv.ColumnPanelRowHeight = PanelRowHeight; // 设置列标题高度
gv.RefreshData(); // 刷新显示
if (dt == null || dt.Rows.Count == 0)
{
return; // 没有数据,直接返回
}
// 更新任务标题,显示任务数量
Trwdb.Text = "[" + pYHJS + "][" + pDQYH + "]工作任务 [" + dt.Rows.Count.ToString().Trim() + "]";
// 收集所有不同的操作按钮名称(与LoadRwgv逻辑相同)
string btmc = "";
string dqmc = "";
for (int r = 0; r < gv.RowCount; r++)
{
dqmc = "[" + gv.GetRowCellValue(r, gv.Columns["rwexec"]).ToString().Trim() + "]";
if (dqmc != "" && !btmc.Contains(dqmc))
{
btmc += dqmc + ",";
}
}
// 如果有操作按钮,重新创建编辑器
if (btmc != "")
{
rcbtmc = btmc.Substring(0, btmc.Length - 1).Split(',');
rcbt = new RepositoryItemButtonEdit[rcbtmc.Length];
for (int i = 0; i < rcbtmc.Length; i++)
{
rcbtmc[i] = rcbtmc[i].Substring(1, rcbtmc[i].Length - 2);
}
// 清理现有的按钮编辑器
for (int i = gd.RepositoryItems.Count - 1; i >= 0; i--)
{
if (gd.RepositoryItems[i].EditorTypeName == "buttonedit")
{
gd.RepositoryItems.RemoveAt(i);
}
}
// 创建新的按钮编辑器
for (int i = 0; i < rcbtmc.Length; i++)
{
if (rcbtmc[i] != "")
{
RepositoryItemButtonEdit rc = new RepositoryItemButtonEdit
{
TextEditStyle = TextEditStyles.HideTextEditor
};
rc.Buttons.Clear();
DevExpress.XtraEditors.Controls.EditorButton bt1 = new DevExpress.XtraEditors.Controls.EditorButton
{
Caption = rcbtmc[i],
Kind = ButtonPredefines.Glyph
};
rc.Buttons.Add(bt1);
rcbt[i] = rc;
gd.RepositoryItems.Add(rcbt[i]);
rcbt[i].ButtonClick += Ljcx_Buttonclick; // 重新绑定事件
}
}
gv.CustomRowCellEdit += Gdgv_Customrowcelledit; // 重新绑定事件
}
}
catch (Exception ex)
{
MsgExShow("刷新工作任务", ex.Message, ex.Source, ex.StackTrace);
}
finally
{
KcDb.DBclose(); // 关闭数据库连接
}
}
/// <summary>
/// 功能按钮点击事件处理
/// 解析Tag中的参数并执行对应的功能
/// 这是左侧导航菜单的核心事件处理器
/// </summary>
/// <param name="sender">事件源(SimpleButton按钮)</param>
/// <param name="e">事件参数</param>
private void RunGncd(object sender, EventArgs e)
{
string[] gntj; // 功能条件数组
string mc; // 功能名称
string bh; // 功能编号
string xz; // 执行权限
string lb; // 功能类别
string ly; // 功能来源
try
{
SimpleButton rx = (SimpleButton)sender; // 获取触发事件的按钮
gntj = rx.Tag.ToString().Split(','); // 解析Tag中的参数
mc = gntj[0]; // 功能名称
ly = gntj[1]; // 功能来源
bh = gntj[2]; // 功能编号
xz = gntj[3]; // 执行权限
lb = gntj[4]; // 功能类别
if (ly == "系统功能") // 系统级功能
{
X9Sys(mc); // 调用系统功能执行方法
}
else // 业务功能
{
X9gn(mc, ly, bh, xz, null, null); // 调用业务功能执行方法
}
}
catch (Exception ex)
{
MsgExShow("执行功能", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 运行功能定义
/// 打开指定类型的功能定义窗口(用于设计模式)
/// </summary>
/// <param name="gnly">功能类别(如:查询输入、单据输入等)</param>
private void RunGndy(string gnly)
{
try
{
// 检查功能定义窗口是否已经打开(避免重复打开)
foreach (Form opfm in Application.OpenForms)
{
if (opfm.Name == "rf0gndy")
{
if (opfm.Text == gnly + "功能定义")
{
// 如果已打开,则激活并前置该窗口
opfm.WindowState = FormWindowState.Normal;
opfm.Activate();
return; // 直接返回,不再创建新窗口
}
}
}
// 创建新的功能定义窗口
FmGndy rf = new FmGndy
{
dygnly = gnly, // 功能类别
fname = gnly + "功能定义" // 窗口标题
};
rf.prfm = this.Text; // 父窗口标题
rf.Show(); // 以非模态方式显示
}
catch (Exception ex)
{
MsgExShow("执行" + gnly + "功能定义", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 运行模板设计
/// 打开打印模板设计窗口(系统功能之一)
/// </summary>
private void RunMbsj()
{
try
{
// 检查模板设计窗口是否已经打开
foreach (Form opfm in Application.OpenForms)
{
if (opfm.Name == "KcRep")
{
opfm.WindowState = FormWindowState.Normal;
opfm.Activate();
return;
}
}
// 创建新的打印模板设计窗口
FmDymb rfrep = new FmDymb();
rfrep.Name = "KcRep";
rfrep.Text = "打印模板设计";
rfrep.Show(); // 以非模态方式显示
}
catch (Exception ex)
{
MsgExShow("执行模板设计功能", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 保存窗口设置
/// 在退出或需要保存状态时调用,保存所有窗口状态到设置中
/// 保存内容:窗口位置大小、分割器位置、选中的标签页、网格列宽等
/// </summary>
private void SaveFmSet()
{
try
{
// 1. 保存主窗口设置(7个参数)
// 格式:Top,Left,Width,Height,SplitterPosition,SelectedTabPageIndex,WindowState
fmset = this.Top.ToString().Trim() + "," +
this.Left.ToString().Trim() + "," +
this.Width.ToString().Trim() + "," +
this.Height.ToString().Trim() + "," +
Sp1.SplitterPosition.ToString().Trim() + "," +
GNTab.SelectedTabPageIndex.ToString().Trim() + "," +
Convert.ToInt32(this.WindowState).ToString();
FmSave("主窗口", fmset);
// 2. 保存任务网格列宽和行高
if (rwgv != null && rwgv.RowCount > 0)
{
fmset = rwgv.VisibleColumns[0].Width.ToString(); // 第一列宽度
for (int c = 1; c < rwgv.VisibleColumns.Count; c++)
{
if (rwgv.VisibleColumns[c].Visible)
{
fmset += "," + rwgv.VisibleColumns[c].Width.ToString().Trim(); // 可见列宽度
}
else
{
fmset += ",0"; // 不可见列宽度为0
}
}
FmSave("任务表格列宽行高", fmset + "," + rwgv.RowHeight.ToString()); // 最后添加行高
}
// 3. 保存状态网格列宽和行高(逻辑类似)
if (ztgv != null && ztgv.RowCount > 0)
{
fmset = ztgv.VisibleColumns[0].Width.ToString();
for (int c = 1; c < ztgv.VisibleColumns.Count; c++)
{
if (ztgv.VisibleColumns[c].Visible)
{
fmset += "," + ztgv.VisibleColumns[c].Width.ToString().Trim();
}
else
{
fmset += ",0";
}
}
FmSave("状态表格列宽行高", fmset + "," + ztgv.RowHeight.ToString());
}
// 4. 保存各功能面板的展开状态
GetZkMk(ywlc); // 业务处理面板
GetZkMk(xxlc); // 信息查询面板
GetZkMk(jclc); // 基础资料面板
}
catch (Exception ex)
{
MsgExShow("保存窗口参数", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 业务日期变更事件
/// 处理状态栏中业务日期的变更,支持手动和自动两种模式
/// </summary>
private void TsYwrq_EditValueChanged(object sender, EventArgs e)
{
// 如果启用手动业务日期模式
if (pGDRQ)
{
string nrq = $"{Tsywrq.EditValue:yyyy-MM-dd}"; // 格式化日期
// 验证日期不能超过当前业务期间
if ((nrq.Substring(0, 4) + nrq.Substring(5, 2)).CompareTo(pYWQJ.Substring(0, 4) + pYWQJ.Substring(4, 2)) > 0)
{
// 如果超过,重置为业务期间的第一天
Tsywrq.EditValue = Convert.ToDateTime(pYWQJ.Substring(0, 4) + "-" + pYWQJ.Substring(4, 2) + "-01");
}
// 保存手动业务日期到参数表
SetZfcs("手动业务日期", $"{Tsywrq.EditValue:yyyy-MM-dd}");
if (pDTCS.DataSet.HasChanges())
{
KcDb.GetDtSaven("x9_ztcs", pDTCS.GetChanges());
pDTCS.AcceptChanges();
}
Tsywrq.Caption = "手动业务日期"; // 更新显示文本
pYWRQ = (DateTime)Tsywrq.EditValue; // 更新全局变量
Tsywrq.Edit.ReadOnly = false; // 允许编辑
}
else // 自动模式(使用系统当前日期)
{
Tsywrq.Caption = "实时业务日期"; // 更新显示文本
pYWRQ = DateTime.Now; // 使用当前日期
Tsywrq.EditValue = DateTime.Now; // 更新控件值
Tsywrq.Edit.ReadOnly = true; // 禁止编辑
}
}
/// <summary>
/// 执行系统功能
/// 根据功能名称调用相应的系统级功能
/// </summary>
/// <param name="mc">功能名称</param>
private void X9Sys(string mc)
{
switch (mc)
{
case "打印模板设计":
RunMbsj(); // 打开打印模板设计窗口
break;
case "电子表格数据交换":
FmEXCEL fjh = new FmEXCEL(); // 创建Excel数据交换窗口
fjh.ShowDialog(this); // 模态显示
fjh = null; // 释放引用
break;
case "数据字典条件编辑":
FmSjzdWh fzd = new FmSjzdWh(); // 创建数据字典维护窗口
fzd.ShowDialog(this); // 模态显示
fzd = null; // 释放引用
break;
// 可以继续添加其他系统功能...
}
}
}
}
六、窗体功能代码说明
(一)概述
FmMain.cs 是“看潮ERP”系统的主窗口类,作为整个ERP系统的核心容器和总控制台,继承自DevExpress的RibbonForm,提供带功能区的高级窗口界面。该窗体负责系统初始化、用户权限管理、功能菜单加载、任务处理等核心功能。
(二)主要功能
1. 窗体初始化与启动
- 构造函数 FmMain():初始化窗体组件并绑定所有事件处理器。
- 窗口加载事件 Form_Load():系统初始化入口,执行环境检查、数据库连接、权限加载、界面构建等操作。
- 主初始化方法 LoadForm():完成所有启动时必要的加载,包括目录创建、参数读取、图标加载、权限验证等。
2. 用户界面管理
- 动态功能菜单加载 (MyGn 方法):根据用户权限动态生成左侧导航面板(基础资料/信息查询/业务处理)。
- 任务列表显示 (LoadRwgv 方法):加载并显示当前用户的待办任务列表,支持任务操作按钮。
- 皮肤/主题设置 (BarSKIN_ItemClick):允许用户更改界面主题。
- Ribbon功能区管理:提供分类目录、功能定义、数据输入、业务处理等功能入口。
3. 权限与安全控制
- 用户权限加载:从数据库读取用户角色和功能权限。
- 授权模块过滤:只显示用户有权限访问的功能模块。
- 密码安全提示:检测用户是否设置登录密码,未设置则强制提示。
- 任务权限验证:执行任务时验证当前用户是否在申请人员列表中。
4. 数据管理
- 数据库连接管理 (BarSJLJ_ItemClick):提供数据库重新连接功能。
- 账套参数管理:加载和保存系统参数设置。
- 配置文件管理:窗口状态、列宽设置等参数的保存和读取。
- 文件目录管理:创建和维护系统所需的各种目录结构。
5. 任务与工作流处理
- 任务列表加载与刷新 (LoadRwgv, Reloadrw):从数据库读取任务并动态配置网格列。
- 任务链接按钮处理 (Ljcx_Buttonclick):处理任务列表中的操作按钮点击,执行相应的任务处理功能。
- 任务状态跟踪:标记任务完成状态,更新任务列表。
6. 系统工具与维护
- 功能定义管理 (RunGndy):在设计模式下打开各类功能定义界面。
- 打印模板设计 (RunMbsj):打开打印模板设计窗口。
- 数据字典配置 (Gdlomyrw):动态配置网格视图列,支持多种编辑器类型。
- 异常日志管理:设计模式下提供异常日志清理功能。
(三)核心数据结构
窗口变量
public static GridView rwgv; // “我的任务”表格视图
public static GridView ztgv; // “系统状态”表格视图
public string cslj; // 系统配置和文件存储的根路径
public DataTable dtgntp; // 功能模块图标数据表
public string fmset; // 窗口设置信息字符串
public ImageCollection gnimage; // 功能图标集合
public LayoutControl jclc, xxlc, ywlc; // 各功能面板的布局控件
public bool pquit; // 退出标志
public string sqmk; // 授权模块字符串
权限相关全局变量
public string pYHJS; // 用户角色
public string pDQYH; // 当前用户
public DataTable pDTQX; // 用户权限数据表
public string pZTMC; // 账套名称
public bool pSFSJ; // 是否设计模式
(四)事件处理机制
1. 功能区按钮事件
- 分类目录、功能列表、各类数据输入/查询/处理功能按钮
- 系统工具:皮肤设置、数据库连接、文件下载等
- 用户管理:密码修改、用户信息查看
2. 任务相关事件
- 任务刷新按钮点击事件
- 任务操作按钮点击事件
- 任务网格右键菜单事件
3. 窗体生命周期事件
- 窗口激活事件:刷新任务列表
- 窗口关闭事件:保存设置并清理资源
- 窗口加载事件:系统初始化
4. 数据变更事件
- 业务日期变更事件
- 打印机选择变更事件
(五)设计特点
1. 动态权限驱动界面
- 根据用户角色动态生成功能菜单
- 按钮状态和可见性基于权限控制
- 模块化分组展示,支持展开/收起
2. 工作流任务集成
- 任务列表与工作流引擎集成
- 支持任务驱动式业务处理
- 多角色协作的任务分配机制
3. 自适应界面设计
- 支持多种屏幕分辨率
- 可保存和恢复窗口布局
- 皮肤/主题切换支持
4. 配置化管理
- 窗口参数、列宽、布局状态可保存
- 业务规则和参数集中管理
- 支持设计模式和运行模式切换
(六)使用注意事项
初始化顺序
- 环境检查和目录创建
- 数据库连接和权限验证
- 参数加载和图标资源初始化
- 功能菜单动态生成
- 任务列表和状态信息加载
权限控制要点
- 功能访问受用户角色控制
- 任务操作需要验证申请人员权限
- 部分系统功能需要管理员权限
异常处理
- 关键操作都有try-catch异常处理
- 异常信息记录和用户提示
- 设计模式下提供异常日志清理
性能优化
- 批量更新操作使用BeginUpdate/EndUpdate
- 图片资源按需加载
- 数据库连接及时关闭
(七)扩展性
新增功能模块
- 在数据库中添加功能定义
- 配置用户权限
- 添加相应的图标资源
- 系统会自动在对应分类中显示
自定义业务规则
- 通过参数表配置业务规则
- 支持公式计算和输入限制
- 可扩展的报表和打印模板
集成第三方组件
- 支持Excel数据交换
- 可扩展的文件关联处理
- 打印和报表功能基于标准组件
(八)相关文件
- FmAbout.cs:关于窗口
- FmSKIN.cs:皮肤设置窗口
- FmYHMM.cs:用户密码修改窗口
- FmYhxx.cs:用户信息查看窗口
- Uf01Flml.cs:功能列表定义窗口
- FmGndy.cs:功能定义窗口
全文总结
文章先以200字点明核心:基于角色与任务重新组织Ribbon、导航、工作区,实现权限级动态菜单与任务流集成;随后给出“摘要+关键词+AI助手”三行规范格式。正文分六章递进:一、通用设计原则强调统一导航、角色仪表盘、高频入口、即时反馈与响应式;二、项目实例展示FmMain窗体“上Ribbon-中Split-下状态栏”细节,指出信息过载、导航深、命名歧义、硬编码等痛点;三、四、五章用3000行C#设计器与业务代码详解布局、控件层次、事件链及初始化流程,覆盖权限表读取、图标缓存、任务网格自定义按钮、参数XML序列化、皮肤切换、打印机列表等实现;六章回顾代码要点与扩展策略。整体为开发者提供一套“可编译、可配置、可复用”的ERP主窗口模板,兼顾视觉专业度与后期维护成本。
(本课题全文完)
更多推荐


所有评论(0)