4-BLMa白龙马C#代码生成器-核心要点

1-BLMa白龙马C#代码生成器-概述
2-BLMa白龙马C#代码生成器-参数设置详解1
3-BLMa白龙马C#代码生成器-参数设置详解2

4.1 PropertyGrid控件的使用

PropertyGrid控件,不仅可以用于控件的属性维护,也可以用于数据的维护,很是方便。比如我项目中用到的【功能管理】


PropertyGrid控件

任何类对象都可以绑定到PropertyGrid上编辑修改,对于值类型的数据直接修改编辑即可,另外枚举、bool类型、日期类型也自动支持,还有字体Font、Color、Size等也自动支持,对于复杂的数据类型需要只定义编辑器,比如下拉列表、弹出窗口等。

PropertyGrid绑定类只要一句代码:

//绑定属性
            pGrid.SelectedObject = codeParam;

4.1自定义下拉编辑器

连接字符串下拉RichTextBox自定义编辑器

核心代码如下:

 /// <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自定义下拉窗口编辑器

PropertyGrid自定义下拉窗口编辑器
 /// <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;
        }

5-BLMa白龙马C#代码生成器-代码示例

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345