1-BLMa白龙马C#代码生成器-概述
2-BLMa白龙马C#代码生成器-参数设置详解1
3-BLMa白龙马C#代码生成器-参数设置详解2
4.1 PropertyGrid控件的使用
PropertyGrid控件,不仅可以用于控件的属性维护,也可以用于数据的维护,很是方便。比如我项目中用到的【功能管理】
任何类对象都可以绑定到PropertyGrid上编辑修改,对于值类型的数据直接修改编辑即可,另外枚举、bool类型、日期类型也自动支持,还有字体Font、Color、Size等也自动支持,对于复杂的数据类型需要只定义编辑器,比如下拉列表、弹出窗口等。
PropertyGrid绑定类只要一句代码:
//绑定属性
pGrid.SelectedObject = codeParam;
4.1自定义下拉编辑器
核心代码如下:
/// <summary>
/// 重载 富文本RichTextBox编辑器
/// </summary>
public class RichTextBoxEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown; //下拉RichTextBox
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if (edSvc != null)
{
if (value is string)
{
RichTextBox rtb = new RichTextBox();
rtb.Text = value as string;
edSvc.DropDownControl(rtb);
return rtb.Text;
}
}
return value;
}
}
4.2自定义弹窗编辑器
本项目没有使用,整体都是在PropertyGrid编辑,弹窗不协调,如果编辑很复杂可以考虑用弹窗
核心代码如下:
/// <summary>
/// 重载 富文本DialogForm 弹窗编辑器
/// </summary>
public class DialogFormEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal; //...弹窗
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if (edSvc != null)
{
if (value is string)
{
EditDialog editForm = new EditDialog(value) { Text = "请编辑长文本" };
edSvc.ShowDialog(editForm);
value = editForm.rtbReturn.Text;
return value;
}
}
return value;
}
}
4.3自定义下拉窗口编辑器
/// <summary>
/// 重载 富文本DialogForm弹窗编辑器 Text + dataGridView
/// </summary>
public class TextTableEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown; //...弹窗
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService edSvc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
if (edSvc != null)
{
if (value is TextDataTable)
{
TextDataTableEditor editForm = new TextDataTableEditor(value as TextDataTable) { Text = "请点击Table_Name列选择表,可多选" };
editForm.TopLevel = false; //把窗口设置为非顶级控件
edSvc.DropDownControl(editForm);
//edSvc.ShowDialog(editForm);
TextDataTable sdt = new TextDataTable();
sdt.tableName = editForm.tbReturn.Text;
sdt.dataTable = editForm.dgvTable.DataSource as DataTable;
return sdt;
}
}
return value;
}
}
其中 TextDataTableEditor为一Form窗口
窗口的构造函数接受PropertyGrid传过来的参数,这里传递的是一个TextDataTable类,包括一个字符串string和一个DataTable。
/// <summary>
/// 自定义表名编辑类
/// </summary>
public class TextDataTable
{
DataTable _dTable = null;
public DataTable dataTable { get { return _dTable; } set { _dTable = value; } }
string _tableName = "Dual";
public string tableName { get { return _tableName; } set { _tableName = value; } }
public override string ToString()
{
return tableName;
}
}
在PropertyGrid里只显示字符串,通过重写 ToString()方法实现,如果不重写在PropertyGrid里只显示类名BLMaCodeGenerator.TextDataTable。
4.2 类的序列化以及反序列化
参数设置保存为XML磁盘文件需要对类序列化,XML反序列化可以转换为参数类CodePrarm
-XML序列化及反序列化代码:
using System;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
namespace BLMaCodeGenerator
{
public static class XMLHelper
{
/// <summary>
/// 对象序列化成 XML String
/// </summary>
public static string XmlSerialize<T>(T obj)
{
string xmlString = string.Empty;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
//using (TextWriter textWriter = new StreamWriter("D:\\xmlTest.xml"))
//{
// xmlSerializer.Serialize(textWriter, obj);
//}
using (MemoryStream ms = new MemoryStream())
{
xmlSerializer.Serialize(ms, obj);
xmlString = Encoding.UTF8.GetString(ms.ToArray());
}
return xmlString;
}
/// <summary>
/// XML String 反序列化成对象
/// </summary>
public static T XmlDeserialize<T>(string xmlString)
{
T t = default(T);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (Stream xmlStream = new MemoryStream(Encoding.UTF8.GetBytes(xmlString)))
{
using (XmlReader xmlReader = XmlReader.Create(xmlStream))
{
Object obj = xmlSerializer.Deserialize(xmlReader);
t = (T)obj;
}
}
return t;
}
}
}
-调用序列化代码:
/// <summary>
/// 保存配置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSave_Click(object sender, EventArgs e)
{
//获取参数列表
CodeParam cp = codeParam;
//将实体对象转换成XML
//string xmlResult = XmlSerializeHelper.XmlSerialize(paramList);
//string xmlResult = XmlSerializeHelper.XmlSerialize(cp);
string xmlResult = XMLHelper.XmlSerialize(cp);
//保存在磁盘文件
string path = Application.StartupPath + @"\XML";
string file = cbSelect.Text.Trim();
SaveToDisk(xmlResult, path, file);
//SaveToDisk(xmlResult);
//刷新cbSelect
string fileName = cbSelect.Text.Trim();
cbSelect.Items.Clear();
ReadSets(fileName);
btnSave.Text = "{[<已保存>]}";
}
/// <summary>
/// String 保存到磁盘
/// </summary>
/// <param name="xmlResult"></param>
private void SaveToDisk(string xmlResult,string path,string file)
{
//保存内容路径+文件
string filename = FileHelper.SaveToDisk(xmlResult, path, file);
cbSelect.Text = filename;
}
-调用反序列化代码:
/// <summary>
/// 读取配置文件绑定到pGrid
/// </summary>
/// <param name="path"></param>
private void BingPgrid(string file)
{
//读取文件
string path = Application.StartupPath + @"\XML";
string pathFile = path + @"\" + file;
string xmlString = FileHelper.ReadXML(pathFile);
//XML反序列化
codeParam = XMLHelper.XmlDeserialize<CodeParam>(xmlString);
//绑定属性
pGrid.SelectedObject = codeParam;
pGrid_PropertyValueChanged(null,null);
}
4.3Oracle数据库表结构
4.3.1Oracle所有用户表
/// <summary>
/// 数据库的全部表
/// </summary>
/// <returns></returns>
public static DataTable AllTables()
{
string sql_tables = @"select TABLE_NAME,COMMENTS ,TABLE_TYPE
from user_tab_comments
where table_type = 'TABLE'
order by table_name";
DataTable allTables = OracleDML.GetDataTable(sql_tables);
allTables.TableName = "allTables";
return allTables;
}
4.3.2 Oracle所用用户列
/// <summary>
/// 表结构信息
/// </summary>
/// <param name="TABLE_NAME"></param>
/// <returns></returns>
public static DataTable TableColumns(string TABLE_NAME)
{
//表结构含主键
string sql_Tbl_Cols = string.Format(@"select t.table_name, t.comments as tab_comments,
d.COLUMN_ID,c.column_name,c.comments as col_comments,
p.position as pk_no, p.constraint_name as pk_name,p.column_name as pk_column,
d.data_type,
decode(d.DATA_TYPE,
'NUMBER',decode(d.data_scale,
null,d.DATA_TYPE,
0,decode(sign(d.DATA_PRECISION - 10),1,'NUMBER10','NUMBER9'),
'NUMBER19')
,d.DATA_TYPE
) AS type_data,
d.DATA_LENGTH,d.data_precision,d.data_scale,d.NULLABLE
from user_tab_comments t
left join user_col_comments c on c.table_name = t.table_name
left join user_tab_columns d on d.table_name = c.table_name and d.column_name = c.column_name
left join (select a.constraint_name, a.column_name ,a.position
from user_cons_columns a, user_constraints b
where a.constraint_name = b.constraint_name
and b.constraint_type = 'P' and a.table_name = '{0}') p on p.column_name = d.column_name
where t.table_type = 'TABLE' and t.table_name = '{0}'
order by t.table_name,p.position,d.COLUMN_ID", TABLE_NAME);
DataTable TableColumns = GetDataTable(sql_Tbl_Cols);
return TableColumns;
}
这里Oracle的数据类型number做了简单的转换,Sql语句如下:
decode(d.DATA_TYPE,
'NUMBER',decode(d.data_scale,
null,d.DATA_TYPE,
0,decode(sign(d.DATA_PRECISION - 10),1,'NUMBER10','NUMBER9'),
'NUMBER19')
,d.DATA_TYPE
) AS type_data
4.4Oracle数据类型和C#数据类型转换
4.4.1数据类型转换
数据类型转化,用HashTable实现。
/// <summary>
/// Oracle数据类型转为C#类型
/// </summary>
/// <param name="oracleType"></param>
/// <returns></returns>
public static string OracleToCSharp(string oracleType)
{
Hashtable ht = DataTypeHT();
string CSharpType = ht[oracleType.ToLower()].ToString();
return CSharpType;
}
/// <summary>
/// oracle数据类型转C#数据类型哈希表
/// </summary>
/// <returns></returns>
public static Hashtable DataTypeHT()
{
//Oracle数据类型变化参阅OracleDML.TableColumns()
Hashtable ht = new Hashtable();
ht.Add("char", "string");
ht.Add("nvarchar", "string");
ht.Add("varchar2", "string");
ht.Add("number", "decimal");
ht.Add("number9", "int");
ht.Add("number10", "long");
ht.Add("number19", "decimal");
ht.Add("date", "DateTime");
return ht;
}
4.4.2表名字段名转换
Oracle的表名和字段名都是保存的大写,分词用下画线,转为为C#的Pascal命名规则,用首字母大写分词。
核心转化代码如下:
/// <summary>
/// 首字符大写并去掉下画线
/// </summary>
/// <param name="STR_ing"></param>
/// <returns></returns>
public static string FirstUpper(string STR_ing)
{
//全小写
string lower = STR_ing.ToLower();
//首字符大写
string First_Upper = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(lower);
//去下画线
string FirstUpper = First_Upper.Replace("_", "");
return FirstUpper;
}