编程与数学 03-008 《看潮企业管理软件》项目开发 08 数据字典 3-2
- 三、功能代码
- 四、功能代码说明
-
- (一)总体概述
- (二)核心业务功能
-
- [1. 数据字典基本操作](#1. 数据字典基本操作)
- [2. 批量列操作](#2. 批量列操作)
- [3. 代码生成工具](#3. 代码生成工具)
- [4. 打印与导出](#4. 打印与导出)
- (三)关键技术实现
-
- [1. 动态编辑器管理](#1. 动态编辑器管理)
- [2. 数据加载策略](#2. 数据加载策略)
- [3. 智能列设置](#3. 智能列设置)
- [4. 版本化管理](#4. 版本化管理)
- (四)数据结构说明
- (五)事件处理机制
- (六)配置与状态管理
-
- [1. 窗体设置持久化](#1. 窗体设置持久化)
- [2. 状态标志](#2. 状态标志)
- [3. 资源管理](#3. 资源管理)
- (七)依赖关系
- (八)使用注意事项
- (九)扩展建议
摘要:本文档详细介绍了《看潮企业管理软件》中数据字典功能的设计与实现。基于C# WinForms与DevExpress XtraGrid控件构建的设计器,配合PostgreSQL存储过程实现数据字典的自动化管理。系统支持字段属性的可视化配置、智能版本继承、动态编辑器分配,并能自动生成C#实体类、DTO及PostgreSQL建表语句。通过元数据标准化管理,有效解决了企业信息系统中的数据一致性、开发效率、界面标准化及系统维护等核心问题,为ERP系统的长期稳定演进提供了基础设施保障。
关键词:数据字典、元数据管理、ERP系统、XtraGrid、DevExpress、PostgreSQL、代码生成、数据一致性、动态编辑器、版本继承
人工智能助手:DeepSeek、Kimi
三、功能代码
C#
/*
文件名称:FmSjzd.cs
功能说明:数据字典管理窗体业务逻辑代码
主要用途:
1. 提供数据库表结构的字典化管理功能
2. 支持数据字典的载入、提交、重置、刷新等操作
3. 生成模型类代码、PostgreSQL建表语句、字段列表文本
4. 提供批量列操作(赋值、清空)
5. 支持打印和数据导出功能
依赖关系:
- 继承自DevExpress.XtraEditors.XtraForm
- 依赖FmSjzd.Designer.cs中的界面布局
- 使用KcErp.KcMain和KcEditgd中的辅助方法
- 数据库操作为x9_sjzd表(数据字典主表)
*/
using DevExpress.Utils;
using DevExpress.Utils.Menu;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using System;
using System.Data;
using System.Windows.Forms;
using static KcErp.KcEditgd;
using static KcErp.KcMain;
namespace KcErp
{
public partial class FmSjzd : DevExpress.XtraEditors.XtraForm
{
#region "fields"
// 窗体字段定义区域
public DataTable dtgnlb; // 功能及数据表列表
public int flds1 = 9; // 更新字段数
public string gnmc; // 功能名称,用于防止重复打开窗口
public int keys1 = 3; // 主键字段数
public string name1 = "x9_sjzd"; // 数据表名
public Form ofm; // 父窗体引用
public string prfm = ""; // 父窗体名称
public string ttbmc = ""; // 当前处理的表名
public short ttxz = 0; // 表类型选项
public string tzdbb = "1501"; // 字典版本号
public string tzdlb = ""; // 字典类别
private string[] colcaption = new string[21]; // 列标题数组
private DataTable dtzd = new DataTable(); // 数据字典DataTable
private GridView gdgv = new GridView(); // 网格视图对象
private RepositoryItemComboBox ricombo1 = new RepositoryItemComboBox(); // 文本类型下拉框
//文本
private RepositoryItemComboBox ricombo2 = new RepositoryItemComboBox(); // 整型类型下拉框
//整型
private RepositoryItemComboBox ricombo3 = new RepositoryItemComboBox(); // 实数类型下拉框
//实数
private RepositoryItemComboBox ricombo4 = new RepositoryItemComboBox(); // 日期类型下拉框
//日期
private RepositoryItemComboBox ricombo5 = new RepositoryItemComboBox(); // 逻辑类型下拉框
//逻辑
private RepositoryItemComboBox ricombof = new RepositoryItemComboBox(); // formattype下拉框
//formattype
private RepositoryItemComboBox ricombom = new RepositoryItemComboBox(); // masktype下拉框
//masktype
private RepositoryItemComboBox ricombos = new RepositoryItemComboBox(); // sumtype下拉框
//数据字典
private bool sftj; // 是否提交标志
private bool sfzr; // 是否载入标志
private string sqltj; // SQL提交语句
#endregion
public FmSjzd()
{
InitializeComponent();
// 绑定窗体事件
this.Load += Form_load;
this.FormClosing += Form_formclosing;
this.Disposed += Form_disposed;
this.Deactivate += Form_deactivate;
// 绑定功能区按钮事件
BarZR.ItemClick += Barbuttonitem3_itemclick;
BarTJ.ItemClick += Barbuttonitem4_itemclick;
BarHELP.ItemClick += Barhelp_itemclick;
BarEXIT.ItemClick += Barexit_itemclick;
BarDY.ItemClick += Bardy_itemclick;
BarF2.ItemClick += Barf2_itemclick;
BarDEL.ItemClick += Bardel_itemclick;
// 绑定控件事件
CBE2.SelectedIndexChanged += Cbe2_selectedindexchanged;
ButtonRF.Click += Buttonrf_click;
ButtonCZ.Click += Buttoncz_click;
ButtonWB.Click += Buttonwb_click;
ButtonpPG.Click += Buttonppg_click;
}
/// <summary>
/// 将字符串首字母大写,其余字母小写
/// </summary>
private static string Dxkt(string str)
{
if (str.Length > 1)
{
return str.Substring(0, 1).ToUpper() + str.Substring(1).ToLower();
}
else
{
return str.ToUpper();
}
}
/// <summary>
/// 载入按钮点击事件 - 执行常规载入
/// </summary>
private void Barbuttonitem3_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Dtzr("0");
}
/// <summary>
/// 提交按钮点击事件 - 提交数据字典修改
/// </summary>
private void Barbuttonitem4_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Dttj();
}
/// <summary>
/// 列清空按钮点击事件 - 清空当前列所有值
/// </summary>
private void Bardel_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (gdgv.RowCount <= 0)
{
return;
}
if (gdgv.FocusedColumn.ReadOnly || (!gdgv.FocusedColumn.OptionsColumn.AllowEdit))
{
return;
}
try
{
int colxh = gdgv.FocusedColumn.VisibleIndex;
if ((colxh < 13))
{
return;
}
string tpname = gdgv.FocusedColumn.ColumnType.Name;
if (tpname.ToLower() != "string")
{
return;
}
if (MsgSfShow("确定要清空此列,本操作只限字符串列!") != DialogResult.OK)
{
return;
}
for (int r = 0; r < gdgv.RowCount; r++)
{
gdgv.SetRowCellValue(r, gdgv.FocusedColumn, "");
}
}
catch (Exception ex)
{
MsgExShow("整列清空", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 打印按钮点击事件 - 打印数据字典
/// </summary>
private void Bardy_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
try
{
gdgv.OptionsPrint.AllowCancelPrintExport = true;
gdgv.OptionsPrint.PrintHeader = true;
gdgv.OptionsPrint.RtfPageHeader = CBE2.Text;
gdgv.ShowRibbonPrintPreview();
}
catch (Exception ex)
{
MsgExShow("打印数据字典", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 返回按钮点击事件 - 保存设置并关闭窗体
/// </summary>
private void Barexit_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
SaveFmSet();
this.Close();
}
/// <summary>
/// 列赋值按钮点击事件 - 为整列赋值
/// </summary>
private void Barf2_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
try
{
if (gdgv.RowCount <= 0)
{
return;
}
if (gdgv.FocusedColumn.ReadOnly || (!gdgv.FocusedColumn.OptionsColumn.AllowEdit))
{
return;
}
int colxh = gdgv.FocusedColumn.VisibleIndex;
if ((colxh < 13))
{
return;
}
string clname = gdgv.FocusedColumn.Caption;
string tpname = gdgv.FocusedColumn.ColumnType.Name;
string clvalue = gdgv.GetRowCellValue(gdgv.FocusedRowHandle, gdgv.FocusedColumn).ToString();
string ipv = "";
ipv = XtraInputBox.Show("请输入列 " + clname + " 的值,该值将被赋于所有行,请谨慎操作", "整列赋值", clvalue);
if (string.IsNullOrEmpty(ipv))
{
return;
}
for (int r = 0; r < gdgv.RowCount; r++)
{
switch (tpname)
{
case "boolean":
gdgv.SetRowCellValue(r, gdgv.FocusedColumn, ipv == "true" ? 1 : 0);
break;
case "decimal":
gdgv.SetRowCellValue(r, gdgv.FocusedColumn, Convert.ToDecimal(ipv));
break;
case "int32":
gdgv.SetRowCellValue(r, gdgv.FocusedColumn, Convert.ToInt32(ipv));
break;
default: //string
gdgv.SetRowCellValue(r, gdgv.FocusedColumn, ipv);
break;
}
}
}
catch (Exception ex)
{
MsgExShow("整列赋值", ex.Message, ex.Source, ex.StackTrace);
return;
}
}
/// <summary>
/// 帮助按钮点击事件 - 打开数据字典帮助
/// </summary>
private void Barhelp_itemclick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
RunHelpsj(this, "数据字典");
}
/// <summary>
/// 重置字段列表按钮点击事件 - 执行重置载入
/// </summary>
private void Buttoncz_click(object sender, EventArgs e)
{
Dtzr("2");
}
/// <summary>
/// 生成DTO模型(未在界面显示)
/// </summary>
private void Buttondto_click(object sender, EventArgs e)
{
Makemodel("dto");
}
/// <summary>
/// 生成实体模型(未在界面显示)
/// </summary>
private void Buttonmd_click(object sender, EventArgs e)
{
Makemodel("");
}
/// <summary>
/// 生成PG语句按钮点击事件 - 生成PostgreSQL建表语句
/// </summary>
private void Buttonppg_click(object sender, EventArgs e)
{
Makepg();
}
/// <summary>
/// 刷新字段列表按钮点击事件 - 执行刷新载入
/// </summary>
private void Buttonrf_click(object sender, EventArgs e)
{
Dtzr("1");
}
/// <summary>
/// 生成列表文本按钮点击事件 - 生成字段列表文本
/// </summary>
private void Buttonwb_click(object sender, EventArgs e)
{
Maketext();
}
/// <summary>
/// 表名选择变化事件 - 自动载入对应表的数据字典
/// </summary>
private void Cbe2_selectedindexchanged(object sender, EventArgs e)
{
if (sfzr && !sftj)
{
Dttj();
}
Dtzr("0");
}
/// <summary>
/// 提交数据字典到数据库
/// </summary>
private void Dttj()
{
CBE2.Focus();
gdgv.PostEditor();
try
{
KcDb.DBopen();
DataTable dt1c = new DataTable();
string xxstr = "";
int xxrecord = 0;
dt1c = dtzd.GetChanges();
if (dt1c != null)
{
xxrecord = dt1c.Rows.Count;
if (KcDb.GetDtSaven(name1, dt1c))
{
dtzd.AcceptChanges();
if (xxrecord > 0)
{
xxstr += Lzdzl.Text + "被提交" + xxrecord.ToString().Trim() + "行";
}
}
}
BarTJ.Enabled = false;
if (!string.IsNullOrEmpty(xxstr.Trim()))
{
MsgXxShow("数据提交已经完成" + Environment.NewLine + Environment.NewLine + xxstr);
}
sftj = true;
KcDb.DBclose();
}
catch (Exception ex)
{
MsgExShow("提交数据", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 载入数据字典
/// </summary>
/// <param name="gx">操作类型:0-常规载入 1-刷新载入 2-重置载入</param>
private void Dtzr(string gx)
{
tzdbb = dtgnlb.DefaultView[CBE2.SelectedIndex]["tzdbb"].ToString();
ttbmc = dtgnlb.DefaultView[CBE2.SelectedIndex]["tname"].ToString();
if (string.IsNullOrEmpty(ttbmc.Trim()))
{
return;
}
try
{
Loadric();
TextBB.Text = tzdbb;
string zdexists = "select case when exists(select tname from x9_sjzd where tname='" + ttbmc +
"' and zdbb='" + tzdbb + "') then 'have' else 'none' end as zdcz;";
string exejg = KcDb.DBString(zdexists);
if (exejg == "none")
{
gx = "1";
}
string exsql1 = "call x9_zrsjzd('" + tzdbb + "','" + ttbmc + "'," + gx + ")";
KcDb.DBexec(exsql1);
string fd = "id,fxh,fname,ftype,flen,fscale,fmemo,fzmc,srlx,byxm,hsxm,alignment,edit," +
"formattype,formatstr,masktype,maskstr,sumtype,sumfmt,search,tooltip";
string sqlzd = string.Format("select " + fd + " from x9_sjzd where zdbb='{0}' and tname='{1}' order by fxh", tzdbb, ttbmc);
dtzd = KcDb.DtRead(sqlzd);
if (dtzd != null)
{
if (dtzd.Rows.Count > 0)
{
GridZD.DataSource = dtzd;
}
}
gdgv.RefreshData();
gdgv.Focus();
L1.Caption = tzdbb + " 数据表名:" + ttbmc + " 共" + dtzd.Rows.Count.ToString().Trim() + "行记录 ";
sfzr = true;
sftj = true;
KcDb.DBclose();
}
catch (Exception ex)
{
MsgExShow("载入数据", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 自动配置列宽菜单点击事件
/// </summary>
private void Dxmenuclick(object sender, EventArgs e)
{
Gvoptionwith(ref gdgv, GridZD.Width);
}
/// <summary>
/// 窗体失活事件 - 激活父窗体
/// </summary>
private void Form_deactivate(object sender, EventArgs e)
{
ofm.Activate();
}
/// <summary>
/// 窗体释放事件 - 清理所有资源
/// </summary>
private void Form_disposed(object sender, EventArgs e)
{
try
{
ofm = null; //form
gnmc = null; //string '所有窗口加此属性,以便不会重复打开
dtgnlb = null; //datatable '功能及数据表列表
name1 = null; //string = "x9_sjzd" '数据表名
keys1 = 0; //integer = 3 '主键字段数
flds1 = 0; //integer = 9 '更新字段数
tzdbb = null; //string = "1501"
ttbmc = null; //string = ""
ttxz = 0; //int16 = 0
sqltj = null; //string '载入条件
dtzd = null; //new datatable '数据字典
sftj = false; //boolean
sfzr = false; //boolean
ricombo1 = null; //new repositoryitemcombobox '文本
ricombo2 = null; //new repositoryitemcombobox '整型
ricombo3 = null; //new repositoryitemcombobox '实数
ricombo4 = null; //new repositoryitemcombobox '日期
ricombo5 = null; //new repositoryitemcombobox '逻辑
ricombom = null; //new repositoryitemcombobox 'masktype
ricombof = null; //new repositoryitemcombobox 'formattype
ricombos = null; //new repositoryitemcombobox 'sumtype
gdgv = null; //new gridview
colcaption = null; //string
RibbonControl = null; //devexpress.xtrabars.ribbon.ribboncontrol
RibbonPage1 = null; //devexpress.xtrabars.ribbon.ribbonpage
RibbonPageGroup1 = null; //devexpress.xtrabars.ribbon.ribbonpagegroup
RibbonStatusBar = null; //devexpress.xtrabars.ribbon.ribbonstatusbar
BarZR = null; //devexpress.xtrabars.barbuttonitem
BarTJ = null; //devexpress.xtrabars.barbuttonitem
Sp1 = null; //devexpress.xtraeditors.splitcontainercontrol
GridZD = null; //devexpress.xtragrid.gridcontrol
GridView1 = null; //devexpress.xtragrid.views.grid.gridview
LabelControl2 = null; //devexpress.xtraeditors.labelcontrol
CBE2 = null; //devexpress.xtraeditors.comboboxedit
L1 = null; //devexpress.xtrabars.barstaticitem
BarCheckItem1 = null; //devexpress.xtrabars.barcheckitem
BarCheckItem2 = null; //devexpress.xtrabars.barcheckitem
BarCheckItem3 = null; //devexpress.xtrabars.barcheckitem
RepositoryItemRadioGroup1 = null; //devexpress.xtraeditors.repository.repositoryitemradiogroup
V1 = null; //devexpress.xtrabars.barcheckitem
V2 = null; //devexpress.xtrabars.barcheckitem
V3 = null; //devexpress.xtrabars.barcheckitem
BarButtonItem5 = null; //devexpress.xtrabars.barbuttonitem
BarButtonItem6 = null; //devexpress.xtrabars.barbuttonitem
BarButtonItem7 = null; //devexpress.xtrabars.barbuttonitem
RibbonPageGroup3 = null; //devexpress.xtrabars.ribbon.ribbonpagegroup
CardView1 = null; //devexpress.xtragrid.views.card.cardview
BackgroundWorker1 = null; //system.componentmodel.backgroundworker
BarHELP = null; //devexpress.xtrabars.barbuttonitem
BarEXIT = null; //devexpress.xtrabars.barbuttonitem
ButtonRF = null; //devexpress.xtraeditors.simplebutton
TextBB = null; //devexpress.xtraeditors.textedit
Lgnmc = null; //devexpress.xtraeditors.labelcontrol
Lzdzl = null; //devexpress.xtraeditors.labelcontrol
GC.Collect();
}
catch (Exception ex)
{
MsgExShow("卸载窗口对象", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 窗体关闭前事件 - 提交未保存的更改
/// </summary>
private void Form_formclosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
{
Dttj();
}
/// <summary>
/// 窗体加载事件 - 初始化界面和数据
/// </summary>
private void Form_load(object sender, System.EventArgs e)
{
string testxh = DateTime.Now.ToString("yyyyMMdd HHmmss ffff");
try
{
SetDg(this, 1800, 600, true);
if (pCdimage.Images.Count > 0)
{
foreach (BarItem item in RibbonControl.Items)
{
if (item.GetType().Name.ToLower() == "barbuttonitem")
{
if (pCdimage.Images.IndexOf(item.Caption) >= 0)
{
((BarButtonItem)item).LargeGlyph = pCdimage.Images[item.Caption];
}
}
}
}
L1.Caption = "";
colcaption[0] = "id";
colcaption[1] = "序号";
colcaption[2] = "字段名称";
colcaption[3] = "类型";
colcaption[4] = "长度";
colcaption[5] = "小数";
colcaption[6] = "标题";
colcaption[7] = "分组";
colcaption[8] = "输入类型";
colcaption[9] = "必要";
colcaption[10] = "行首";
colcaption[11] = "对齐";
colcaption[12] = "控件";
colcaption[13] = "格式类型";
colcaption[14] = "格式字符";
colcaption[15] = "掩码类型";
colcaption[16] = "掩码字符";
colcaption[17] = "摘要类型";
colcaption[18] = "摘要格式";
colcaption[19] = "上网搜索";
colcaption[20] = "操作提示";
Loadgv();
CBE2.Properties.Items.Clear();
for (int i = 0; i < dtgnlb.Rows.Count; i++)
{
CBE2.Properties.Items.Add(dtgnlb.Rows[i]["tname"].ToString() +
(string.IsNullOrEmpty(dtgnlb.Rows[i]["tzdbb"].ToString()) ? "" :
"[" + dtgnlb.Rows[i]["tzdbb"] + "]"));
}
BarTJ.Enabled = false;
if (CBE2.Properties.Items.Count > 0)
{
if (ttxz == 1)
{
CBE2.SelectedIndex = 1;
}
else
{
CBE2.SelectedIndex = 0;
}
}
}
catch (Exception ex)
{
MsgExShow("加载程序", ex.Message, ex.Source, ex.StackTrace);
}
try
{
string fmset = FmRead(this.Text);
string[] fmay = fmset.Split(',');
if (fmay.Length == 6)
{
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]) > 50) this.Width = Convert.ToInt32(fmay[2]);
if (Convert.ToInt32(fmay[3]) > 50) this.Height = Convert.ToInt32(fmay[3]);
if (Convert.ToInt32(fmay[4]) > 50) Sp1.SplitterPosition = Convert.ToInt32(fmay[4]);
if (Convert.ToInt32(fmay[5]) > 16)
{
gdgv.RowHeight = Convert.ToInt32(fmay[5]);
}
}
if (gdgv != null)
{
fmset = FmRead(this.Text + "表格");
fmay = fmset.Split(',');
if (fmay.Length >= gdgv.Columns.Count)
{
for (int c = 0; c < gdgv.Columns.Count; c++)
{
int cw = Convert.ToInt32(fmay[c]);
if (cw <= 0)
{
gdgv.Columns[c].Visible = false;
}
else
{
gdgv.Columns[c].Width = cw;
}
}
}
else
{
Gvoptionwith(ref gdgv, GridZD.Width);
}
}
}
catch (Exception ex)
{
MsgExShow("应用保存的窗口参数", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 网格自定义单元格编辑器事件 - 根据字段类型动态设置编辑器
/// </summary>
private void Gdgv_customrowcelledit(object sender, CustomRowCellEditEventArgs e)
{
try
{
if (gdgv.Columns.Count <= 0) return;
if (e.RowHandle < 0) return;
if (e.Column.FieldName == "edit")
{
string fn = gdgv.GetRowCellValue(e.RowHandle, "srlx").ToString();
e.RepositoryItem = Rc(fn);
}
if (e.Column.FieldName == "masktype")
{
string fn = gdgv.GetRowCellValue(e.RowHandle, "srlx").ToString();
e.RepositoryItem = Rm(fn);
}
if (e.Column.FieldName == "formattype")
{
string fn = gdgv.GetRowCellValue(e.RowHandle, "srlx").ToString();
e.RepositoryItem = Rf(fn);
}
if (e.Column.FieldName == "sumtype")
{
string fn = gdgv.GetRowCellValue(e.RowHandle, "srlx").ToString();
e.RepositoryItem = Rs(fn);
}
}
catch (Exception) { }
}
/// <summary>
/// 网格视图格式化设置
/// </summary>
private void Gvft()
{
Setgv(ref gdgv, true);
gdgv.Columns[0].Visible = false;
for (int i = 0; i < gdgv.Columns.Count; i++)
{
gdgv.Columns[i].Caption = colcaption[i];
gdgv.Columns[i].OptionsColumn.ReadOnly = (i < 6);
gdgv.Columns[i].Fixed = (i < 6) ? FixedStyle.Left : FixedStyle.None;
gdgv.Columns[i].AppearanceHeader.Options.UseTextOptions = true;
gdgv.Columns[i].AppearanceHeader.TextOptions.HAlignment = HorzAlignment.Center;
gdgv.Columns[i].AppearanceHeader.TextOptions.VAlignment = VertAlignment.Center;
gdgv.Columns[i].AppearanceCell.Options.UseTextOptions = true;
gdgv.Columns[i].AppearanceCell.TextOptions.VAlignment = VertAlignment.Center;
switch (i)
{
case 2:
case 3:
case 6:
case 8:
case 7:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
gdgv.Columns[i].AppearanceCell.TextOptions.HAlignment = HorzAlignment.Near;
break;
default:
gdgv.Columns[i].AppearanceCell.TextOptions.HAlignment = HorzAlignment.Center;
break;
}
}
gdgv.CustomRowCellEdit += Gdgv_customrowcelledit;
gdgv.KeyUp += View_keyup;
gdgv.CellValueChanged += View_cellvaluechanged;
}
/// <summary>
/// 加载网格视图
/// </summary>
private void Loadgv()
{
try
{
string fd = "id,fxh,fname,ftype,flen,fscale,fmemo,fzmc,srlx,byxm,hsxm,alignment,edit,formattype,formatstr," +
"masktype,maskstr,sumtype,sumfmt,search,tooltip";
string sqlzd = string.Format("select " + fd + " from x9_sjzd where 1=0 AND zdbb='{0}' and tname='{1}' order by fxh", "", "");
dtzd = KcDb.DtRead(sqlzd);
if (dtzd != null)
{
GridZD.ViewCollection.Clear();
gdgv.OptionsBehavior.AutoPopulateColumns = false;
GridZD.DataSource = dtzd;
gdgv = new GridView(GridZD);
gdgv.OptionsSelection.MultiSelect = true;
gdgv.OptionsSelection.MultiSelectMode = DevExpress.XtraGrid.Views.Grid.GridMultiSelectMode.RowSelect;
gdgv.OptionsView.EnableAppearanceEvenRow = true;
gdgv.OptionsView.EnableAppearanceOddRow = true;
GridZD.MainView = gdgv;
gdgv.PopulateColumns();
gdgv.PopupMenuShowing += Mtgv_popupmenushowing;
Gvft();
}
KcDb.DBclose();
}
catch (Exception ex)
{
MsgExShow("初始表格视图", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 加载下拉框资源
/// </summary>
private void Loadric()
{
if (tzdbb == "kcrj")
{
//设计器
ricombo1.Items.Clear();
ricombo1.Items.Add("field");
ricombo1.Items.Add("fieldlist");
ricombo1.Items.Add("fieldlistex");
ricombo1.Items.Add("textedit");
ricombo1.Items.Add("texteditex");
ricombo1.Items.Add("memoedit");
ricombo2.Items.Clear();
ricombo2.Items.Add("textedit");
ricombo3.Items.Clear();
ricombo3.Items.Add("textedit");
ricombo4.Items.Clear();
ricombo4.Items.Add("textedit");
ricombo4.Items.Add("dateedit");
ricombo5.Items.Clear();
ricombo5.Items.Add("checkedit");
}
else
{
//用户功能
ricombo1.Items.Clear();
ricombo1.Items.Add("textedit");
ricombo1.Items.Add("textread");
ricombo1.Items.Add("notenter");
ricombo1.Items.Add("comboedit");
ricombo1.Items.Add("listedit");
ricombo1.Items.Add("buttonedit");
ricombo1.Items.Add("buttonggxh");
ricombo1.Items.Add("buttontextedit");
ricombo1.Items.Add("buttontextread");
ricombo1.Items.Add("checkedcomboedit");
ricombo1.Items.Add("checkedlistedit");
ricombo1.Items.Add("autonumber");
ricombo1.Items.Add("memoedit");
ricombo1.Items.Add("memoread");
ricombo1.Items.Add("hyperlinkedit");
ricombo1.Items.Add("fileedit");
ricombo1.Items.Add("fileread");
ricombo1.Items.Add("richtextedit");
ricombo1.Items.Add("richtextread");
ricombo2.Items.Clear();
ricombo2.Items.Add("textedit");
ricombo2.Items.Add("textread");
ricombo2.Items.Add("notenter");
ricombo2.Items.Add("autonumber");
ricombo2.Items.Add("buttonedit");
ricombo2.Items.Add("calcedit");
ricombo2.Items.Add("coloredit");
ricombo2.Items.Add("spinedit");
ricombo3.Items.Clear();
ricombo3.Items.Add("textedit");
ricombo3.Items.Add("textread");
ricombo3.Items.Add("notenter");
ricombo3.Items.Add("calcedit");
ricombo3.Items.Add("spinedit");
ricombo4.Items.Clear();
ricombo4.Items.Add("dateedit");
ricombo4.Items.Add("textedit");
ricombo4.Items.Add("textread");
ricombo4.Items.Add("notenter");
ricombo5.Items.Clear();
ricombo5.Items.Add("checkedit");
ricombo5.Items.Add("checkread");
}
ricombom.Items.Clear();
ricombom.Items.Add("");
ricombom.Items.Add("numeric");
ricombom.Items.Add("datetime");
ricombom.Items.Add("simple");
ricombom.Items.Add("regular");
ricombom.Items.Add("regex");
ricombom.Items.Add("custom");
ricombof.Items.Clear();
ricombof.Items.Add("");
ricombof.Items.Add("datetime");
ricombof.Items.Add("numeric");
ricombof.Items.Add("custom");
ricombos.Items.Clear();
ricombos.Items.Add("");
ricombos.Items.Add("sum");
ricombos.Items.Add("average");
ricombos.Items.Add("count");
ricombos.Items.Add("max");
ricombos.Items.Add("min");
ricombo1.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombo2.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombo3.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombo4.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombo5.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombom.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombof.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombos.TextEditStyle = TextEditStyles.DisableTextEditor;
ricombo1.DropDownRows = 15;
ricombo2.DropDownRows = 15;
ricombo3.DropDownRows = 15;
ricombo4.DropDownRows = 15;
ricombo5.DropDownRows = 15;
ricombom.DropDownRows = 15;
ricombof.DropDownRows = 15;
ricombos.DropDownRows = 10;
GridZD.RepositoryItems.Clear();
GridZD.RepositoryItems.Add(ricombo1);
GridZD.RepositoryItems.Add(ricombo2);
GridZD.RepositoryItems.Add(ricombo3);
GridZD.RepositoryItems.Add(ricombo4);
GridZD.RepositoryItems.Add(ricombo5);
GridZD.RepositoryItems.Add(ricombom);
GridZD.RepositoryItems.Add(ricombof);
GridZD.RepositoryItems.Add(ricombos);
}
/// <summary>
/// 生成模型类代码
/// </summary>
/// <param name="str">模型类型:空-实体模型 dto-DTO模型</param>
private void Makemodel(string str)
{
string mdstr = "";
string tbname = ttbmc.Replace("_", "").ToLower();
tbname = Dxkt(tbname);
mdstr += " //看潮企业管理软件 生成代码 岳国军 " + Environment.NewLine;
mdstr += " // " + Environment.NewLine;
if (str == "")
{
mdstr += " [table(\"" + ttbmc + "\")]" + Environment.NewLine;
}
mdstr += " public class " + tbname + str + Environment.NewLine;
mdstr += " {" + Environment.NewLine;
if (str == "")
{
mdstr += " [key]" + Environment.NewLine;
}
for (int i = 0; i < dtzd.Rows.Count; i++)
{
DataRow row = dtzd.Rows[i];
if (str == "dto" && !string.IsNullOrEmpty(tzdlb))
{
if (tzdlb.IndexOf(row["fname"].ToString()) <= 1)
{
continue;
}
}
string ftype = row["ftype"].ToString().ToLower();
string flen = row["flen"].ToString().Trim();
string colname = row["fname"].ToString().ToLower();
string coltype = ""; //注释类型
string typestr = "";
switch (ftype)
{
case "bit":
typestr = "bool";
coltype = "typename = \"bit\"";
break;
case "smallint":
typestr = "sbyte";
coltype = "typename = \"smallint\"";
break;
case "bigint":
case "int":
case "tinyint":
typestr = "int";
coltype = "typename = \"int\"";
break;
case "numeric":
case "decimal":
case "money":
case "smallmoney":
case "float":
case "real":
typestr = "double";
coltype = "typename = \"decimal(16,2)\"";
break;
case "date":
case "datetime":
case "datetime2":
typestr = "DateTime";
coltype = "typename = \"datetime\")";
break;
case "char":
case "varchar":
case "text":
typestr = "string";
coltype = "typename = \"" + ftype + "(" + flen + ")" + "\"";
break;
case "nchar":
case "nvarchar":
case "ntext":
typestr = "string";
coltype = "typename = \"" + ftype + "\"";
coltype = " [maxlength(" + flen + ")]";
break;
}
mdstr += " /// <summary>" + Environment.NewLine;
mdstr += " ///" + row["fmemo"].ToString() + " " + row["edit"].ToString() + Environment.NewLine;
mdstr += " /// </summary>" + Environment.NewLine;
if (!string.IsNullOrEmpty(coltype) && str == "")
{
mdstr += " [column(\"" + colname.ToLower() + "\"," + coltype + ")]" + Environment.NewLine;
if (Convert.ToBoolean(row["byxm"]))
{
mdstr += " [required]" + Environment.NewLine;
}
}
mdstr += " public " + typestr + " " + Dxkt(colname) + " { get; set; }" + Environment.NewLine;
}
mdstr += "}" + Environment.NewLine;
Clipboard.SetText(mdstr);
}
/// <summary>
/// 生成PostgreSQL建表语句
/// </summary>
private void Makepg()
{
string mdstr = "";
string tbname = ttbmc.Replace("_", "").ToLower();
string tbkey = "";
tbname = Dxkt(tbname);
mdstr += "--看潮企业管理软件 生成代码 岳国军 " + Environment.NewLine;
mdstr += "--" + Environment.NewLine;
mdstr += "-- drop table if exists public." + tbname + ";" + Environment.NewLine;
mdstr += "create table if not exists public." + tbname + Environment.NewLine;
mdstr += "(" + Environment.NewLine;
for (int i = 0; i < dtzd.Rows.Count; i++)
{
DataRow row = dtzd.Rows[i];
string ftype = row["ftype"].ToString().ToLower();
string flen = row["flen"].ToString().Trim();
string colname = row["fname"].ToString().ToLower();
string typestr = "";
switch (ftype)
{
case "bit":
typestr = "boolean not null";
break;
case "smallint":
typestr = "smallint not null default 0";
break;
case "bigint":
case "int":
case "tinyint":
typestr = "integer not null default 0";
break;
case "numeric":
case "decimal":
case "money":
case "smallmoney":
case "float":
case "real":
typestr = "numeric(16,2) not null default 0";
break;
case "date":
typestr = "date";
break;
case "datetime":
typestr = "timestamp with time zone";
break;
case "time":
typestr = "time";
break;
case "char":
case "nchar":
typestr = "character(" + flen + ") collate pg_catalog.\"default\" not null default ''::bpchar";
break;
case "varchar":
case "nvarchar":
typestr = "character varying(" + flen + ") collate pg_catalog.\"default\" not null default ''::character varying";
break;
case "image":
case "varcinary":
typestr = "bytea";
break;
default:
break;
}
if (i == 0)
{
tbkey = colname;
}
if (colname == "id" && ftype == "int")
{
typestr = "integer not null default nextval('" + colname + "_serial_seq'::regclass)";
}
mdstr += " " + colname + " " + typestr + "," + Environment.NewLine;
}
mdstr += " constraint " + tbname + "_pkey primary key (" + tbkey + ")" + Environment.NewLine;
mdstr += ")" + Environment.NewLine;
mdstr += "tablespace pg_default;" + Environment.NewLine;
mdstr += "alter table if exists public." + tbname + " owner to pghy;" + Environment.NewLine;
Clipboard.SetText(mdstr);
}
/// <summary>
/// 生成字段列表文本
/// </summary>
private void Maketext()
{
string mdstr = "";
string tbname = ttbmc.ToLower();
mdstr += ttbmc + "字段列表:" + Environment.NewLine + Environment.NewLine;
for (int i = 0; i < dtzd.Rows.Count; i++)
{
DataRow row = dtzd.Rows[i];
mdstr += string.Format("{0,-8}", row["fname"]) + "\t";
mdstr += string.Format("{0,-8}", row["ftype"]) + "\t";
mdstr += string.Format("{0,5}", row["flen"]) + "\t";
mdstr += string.Format("{0,-12}", row["fmemo"]) + "\t";
mdstr += string.Format("{0,-8}", row["edit"]) + "\t";
mdstr += string.Format("{0,8}", row["formatstr"]) + Environment.NewLine;
}
mdstr += Environment.NewLine;
Clipboard.SetText(mdstr);
}
/// <summary>
/// 网格右键菜单显示事件 - 添加自定义菜单项
/// </summary>
private void Mtgv_popupmenushowing(object sender, DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventArgs e)
{
try
{
if (e.Menu == null)
{
return;
}
if (e.HitInfo.InColumnPanel)
{
DXMenuItem dxmenu = new DXMenuItem();
dxmenu.Caption = "自动配置列宽";
dxmenu.Click += Dxmenuclick;
e.Menu.Items.Add(dxmenu);
}
}
catch (Exception ex)
{
MsgExShow("增加配置列宽右键菜单", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 根据字段类型获取对应的编辑器下拉框
/// </summary>
private RepositoryItemComboBox Rc(string str)
{
switch (str)
{
case "文本":
return ricombo1;
case "整型":
return ricombo2;
case "数值":
return ricombo3;
case "日期时间":
return ricombo4;
case "逻辑":
return ricombo5;
default:
return null;
}
}
/// <summary>
/// 根据字段类型获取格式类型下拉框
/// </summary>
private RepositoryItemComboBox Rf(string str)
{
switch (str)
{
case "文本":
case "整型":
case "数值":
case "日期时间":
return ricombof;
default:
return null;
}
}
/// <summary>
/// 根据字段类型获取掩码类型下拉框
/// </summary>
private RepositoryItemComboBox Rm(string str)
{
switch (str)
{
case "文本":
case "整型":
case "数值":
case "日期时间":
return ricombom;
default:
return null;
}
}
/// <summary>
/// 根据字段类型获取摘要类型下拉框
/// </summary>
private RepositoryItemComboBox Rs(string str)
{
switch (str)
{
case "文本":
case "整型":
case "数值":
case "日期时间":
return ricombos;
default:
return null;
}
}
/// <summary>
/// 保存窗体设置
/// </summary>
private void SaveFmSet()
{
if (this.WindowState != FormWindowState.Normal)
{
return;
}
try
{
string fmset;
fmset = this.Top.ToString() + "," + this.Left.ToString() + "," + this.Width.ToString() + "," + this.Height.ToString() + "," +
Sp1.SplitterPosition.ToString() + "," + (gdgv == null ? "25" : gdgv.RowHeight.ToString());
if (this.WindowState == FormWindowState.Normal) FmSave(this.Text, fmset);
if (gdgv != null)
{
if (gdgv.RowCount > 0)
{
fmset = gdgv.Columns[0].Width.ToString().Trim();
for (int g = 1; g < gdgv.Columns.Count; g++)
{
fmset = fmset + "," + gdgv.Columns[g].Width.ToString().Trim();
}
FmSave(this.Text + "表格", fmset);
}
}
}
catch (Exception ex)
{
MsgExShow("保存窗口参数", ex.Message, ex.Source, ex.StackTrace);
}
}
/// <summary>
/// 设置网格视图属性
/// </summary>
private void Setgv(ref GridView gv, bool bj)
{
gv.RowHeight = 30;
gv.ColumnPanelRowHeight = PanelRowHeight;
gv.Appearance.HeaderPanel.TextOptions.VAlignment = VertAlignment.Center;
gv.Appearance.HeaderPanel.TextOptions.HAlignment = HorzAlignment.Center;
gv.Appearance.HeaderPanel.TextOptions.WordWrap = WordWrap.Wrap;
gv.IndicatorWidth = 20;
gv.OptionsCustomization.AllowRowSizing = true;
gv.OptionsView.ShowGroupPanel = false;
gv.OptionsView.ShowGroupedColumns = false;
gv.OptionsView.ColumnAutoWidth = false;
gv.OptionsView.NewItemRowPosition = NewItemRowPosition.None;
gv.OptionsView.ShowFooter = false;
gv.OptionsBehavior.ReadOnly = !bj;
}
/// <summary>
/// 单元格值改变事件 - 启用提交按钮
/// </summary>
private void View_cellvaluechanged(object sender, CellValueChangedEventArgs e)
{
if (!sfzr) return;
if (sftj)
{
sftj = false;
BarTJ.Enabled = true;
}
}
/// <summary>
/// 键盘按键事件 - 回车键移到下一单元格
/// </summary>
private void View_keyup(object sender, KeyEventArgs e)
{
//回车后移至下一单元格
if (e.KeyCode == Keys.Enter)
{
SendKeys.Send("{down}");
SendKeys.Send("{enter}");
}
}
}
}
四、功能代码说明
窗体功能代码说明文档:FmSjzd.cs
(一)总体概述
文件类型:C# Windows Forms 业务逻辑代码文件
对应窗体:FmSjzd(数据字典管理窗体)
核心功能:提供企业管理系统中的数据字典配置管理功能
开发框架:.NET WinForms + DevExpress界面控件
数据库表:x9_sjzd(数据字典主表)
(二)核心业务功能
1. 数据字典基本操作
| 功能 | 方法 | 描述 |
|---|---|---|
| 载入数据 | Dtzr(string gx) |
从数据库加载指定表的数据字典信息 |
| 提交修改 | Dttj() |
将修改保存到数据库 |
| 刷新字段 | Buttonrf_click() |
根据表结构刷新字段列表 |
| 重置字段 | Buttoncz_click() |
重置字典信息并更新字段列表 |
2. 批量列操作
| 功能 | 方法 | 快捷键 | 适用列类型 |
|---|---|---|---|
| 整列赋值 | Barf2_itemclick() |
Ctrl+F2 | 字符串、数值、布尔、日期 |
| 整列清空 | Bardel_itemclick() |
Ctrl+Delete | 仅字符串列 |
3. 代码生成工具
| 生成类型 | 方法 | 输出格式 | 用途 |
|---|---|---|---|
| 实体模型 | Makemodel("") |
C#类代码 | ORM实体类生成 |
| DTO模型 | Makemodel("dto") |
C#类代码 | 数据传输对象 |
| PostgreSQL | Makepg() |
SQL建表语句 | 数据库迁移 |
| 字段文本 | Maketext() |
格式化文本 | 文档输出 |
4. 打印与导出
| 功能 | 方法 | 输出格式 |
|---|---|---|
| 打印预览 | Bardy_itemclick() |
网格打印 |
| 帮助文档 | Barhelp_itemclick() |
在线帮助 |
(三)关键技术实现
1. 动态编辑器管理
csharp
// 根据字段类型动态分配编辑器
private void Gdgv_customrowcelledit(object sender, CustomRowCellEditEventArgs e)
{
if (e.Column.FieldName == "edit")
{
string fn = gdgv.GetRowCellValue(e.RowHandle, "srlx").ToString();
e.RepositoryItem = Rc(fn); // 根据输入类型返回对应编辑器
}
}
2. 数据加载策略
csharp
private void Dtzr(string gx) // gx参数说明:
{
// 0 - 常规载入(仅加载现有数据)
// 1 - 刷新载入(重新从表结构生成)
// 2 - 重置载入(删除旧数据重新生成)
string exsql1 = "call x9_zrsjzd('" + tzdbb + "','" + ttbmc + "'," + gx + ")";
KcDb.DBexec(exsql1); // 调用存储过程处理
}
3. 智能列设置
- 只读控制:前6列(id-fscale)为只读字段
- 固定列:前6列固定在左侧
- 对齐方式:数值居中对齐,文本左对齐
- 动态列宽:支持右键菜单自动配置列宽
4. 版本化管理
csharp
public string tzdbb = "1501"; // 字典版本号
public string tzdlb = ""; // 字典类别
- 支持多版本数据字典并存
- 按版本号和表名唯一标识字典项
(四)数据结构说明
数据字典字段说明(x9_sjzd表)
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | int | 主键ID |
| fxh | int | 字段序号 |
| fname | varchar | 字段名称 |
| ftype | varchar | 数据类型 |
| flen | int | 字段长度 |
| fscale | int | 小数位数 |
| fmemo | nvarchar | 字段说明 |
| fzmc | nvarchar | 分组名称 |
| srlx | varchar | 输入类型(文本/整型/数值/日期/逻辑) |
| byxm | bit | 必要项目 |
| hsxm | bit | 行首项目 |
| alignment | varchar | 对齐方式 |
| edit | varchar | 编辑控件类型 |
| formattype | varchar | 格式类型 |
| formatstr | varchar | 格式字符 |
| masktype | varchar | 掩码类型 |
| maskstr | varchar | 掩码字符 |
| sumtype | varchar | 摘要类型 |
| sumfmt | varchar | 摘要格式 |
| search | bit | 是否可搜索 |
| tooltip | nvarchar | 操作提示 |
输入类型对应编辑器
| 输入类型 | 可用编辑器 |
|---|---|
| 文本 | textedit、comboedit、buttonedit等19种 |
| 整型 | textedit、spinedit、calcedit等8种 |
| 数值 | textedit、spinedit、calcedit等5种 |
| 日期时间 | dateedit、textedit等4种 |
| 逻辑 | checkedit、checkread |
(五)事件处理机制
窗体生命周期事件
- Form_load:初始化界面、加载数据、应用保存的设置
- Form_formclosing:自动提交未保存的更改
- Form_disposed:彻底清理所有资源,防止内存泄漏
- Form_deactivate:激活父窗体,保持程序焦点
用户交互事件
- CBE2_selectedindexchanged:表名变更时自动加载对应字典
- View_cellvaluechanged:检测数据修改,启用提交按钮
- View_keyup:回车键自动跳转至下一单元格
右键菜单扩展
csharp
private void Mtgv_popupmenushowing()
{
// 在列标题区域右键时添加"自动配置列宽"菜单项
if (e.HitInfo.InColumnPanel)
{
DXMenuItem dxmenu = new DXMenuItem();
dxmenu.Caption = "自动配置列宽";
dxmenu.Click += Dxmenuclick;
}
}
(六)配置与状态管理
1. 窗体设置持久化
csharp
private void SaveFmSet()
{
// 保存窗体位置、大小、分割器位置、行高
// 保存表格列宽设置(各列宽度用逗号分隔)
}
2. 状态标志
| 标志 | 类型 | 说明 |
|---|---|---|
| sfzr | bool | 是否已载入数据 |
| sftj | bool | 数据是否需要提交 |
| ttxz | short | 表类型选项(0-普通表,1-系统表) |
3. 资源管理
- 图像资源:从pCdimage集合加载功能区按钮图标
- 下拉框资源:根据版本类型(kcrj/其他)加载不同的编辑器选项
- 内存清理:Form_disposed中显式释放所有对象并调用GC.Collect()
(七)依赖关系
内部依赖
- KcDb类:数据库操作封装
- KcMain类:通用工具方法(MsgExShow、FmSave等)
- KcEditgd类:网格视图工具方法
外部依赖
- DevExpress组件:XtraBars、XtraGrid、XtraEditors
- .NET Framework:System.Data、System.Windows.Forms
(八)使用注意事项
开发注意事项
- 事件绑定:在构造函数中完成所有事件绑定
- 资源释放:Form_disposed必须确保所有对象为null
- 数据库连接:每个操作后必须关闭数据库连接
- 线程安全:BackgroundWorker支持取消操作
运行时注意事项
- 数据提交:窗体关闭前自动提交修改,无需手动保存
- 列操作限制:列赋值/清空仅对13列之后的列有效
- 版本兼容:不同版本的数据字典可能使用不同的编辑器集合
- 性能考虑:大量数据时批量操作需谨慎
(九)扩展建议
功能扩展
- 导入/导出:支持Excel、XML格式的字典导入导出
- 版本对比:不同版本数据字典的差异比较
- 字段验证:添加字段值验证规则配置
- 权限控制:基于角色的字典编辑权限
技术优化
- 异步加载:大数据量时使用异步方式加载
- 缓存机制:常用字典信息缓存到本地
- 模板管理:可保存和复用字典配置模板
- 批量操作:支持多表同时操作