• .NET C/S(WinForm)开发技巧点滴(转)


    花费了十天时间,为公司开发了一套简单的网络版的信息管理系统,功能主要有客户信息管理,员工信息管理,常用信息管理(各种信函打印、常用网址/常用电话等),公司简单的财务管理等。把一些点点滴滴的技巧在此记录下来,以备查用。

    1.数据绑定。 DataReader 读取数据,用DataTable.Load(IDataReader)方法将数据加载到 DataTable ,用DataGridView 显示输出。不要把DataGridView直接绑定到DataReader的目的是数据导出到Excel时,数据源可以再次从DataGridView获得。
    不要在 DataGridView 内编辑添加数据,因为数据类型检查不严格(或要严格检查类型需要花费更大的成本)。

    2.数据导出到 Excel 。代码如下:

     

    /**//// <summary>
    /// 
    /// ** DataTable 数据导出到 Excel **
    ///
    ///  Author: 周振兴 (Zxjay 飘遥)
    /// 
    ///  E-Mail: tda7264@163.com
    /// 
    ///  Blog: http://blog.csdn.net/zxjay
    /// 
    ///  Date: 07-08-31
    /// 
    /// </summary>

                    Excel.Application app = new Excel.Application();
                    app.Visible 
    = false;
                    Excel.Workbook wb 
    = app.Workbooks.Add(true);
                    Excel.Worksheet ws 
    = (Excel.Worksheet)wb.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, 

    Type.Missing);

                    DataTable dt 
    = (DataTable)dgvClientInfo.DataSource;

                    
    for (int i = 0; i < dt.Columns.Count; i++)
                    
    {
                        ws.Cells[
    1, i + 1= dt.Columns[i].ColumnName;
                    }


                    
    for (int j = 0; j < dt.Rows.Count; j++)
                    
    {
                        
    for (int k = 0; k < dt.Columns.Count; k++)
                        
    {
                            ws.Cells[j 
    + 2, k + 1= dt.Rows[j][k];
                        }

                    }

                    app.Visible 
    = true;


    注意:Excel的Cells[,]下标是从1,1开始的,而不是0,0。

    3.防止子窗口重复打开,确保某一子窗口只打开一次。代码为:

     foreach (Form frm in this.MdiChildren)
                
    {
                    
    if (frm is WorkerList)
                    
    {
                        frm.WindowState 
    = FormWindowState.Normal;
                        frm.Activate();
                        
    return;
                    }

                }


                WorkerList wl 
    = new WorkerList();
                wl.MdiParent 
    = this;
                wl.Show();

    4.使用枚举 enum 区分类同信息。

    硬编码方式容易造成混乱。如本系统的常用电话/常用网址,数据项都为:名称-内容-备注,可将它们保存在同一个表中,在程序中为区分信息类型,可定义以下枚举:

     

        public enum TelWeb
        
    {
            Telephone,WebSite
        }


    5.在ToolStrip中加入其它WinForm控件。

    如在ToolStrip中加入DateTimePicker。如图:

    Code


    6.用微软的可打印的富文本框控件打印带格式的文本。

    与.NETFX自带的RichTextBox相比只增强了打印功能。通过该控件,可设置文本字体、颜色、对齐方式、粘贴图片,可打印看上去很专业的文档,截图如下:



    参考:http://support.microsoft.com/kb/812425/zh-cn

    7.保存富文本格式到数据库。

    以二进制格式保存。保存的代码为:

                MemoryStream ms = new MemoryStream();
                rtbContent.SaveFile(ms, RichTextBoxStreamType.RichText);
                
    byte[] bt=ms.ToArray(); //将bt保存到数据库

    读取的代码为:

                byte[] bt = (byte[])SqlHelper.ExecuteScalar(sqlStr, null);
                MemoryStream ms 
    = new MemoryStream(bt, false);
                rtbContent.LoadFile(ms, RichTextBoxStreamType.RichText);

    在SQLServer中对应的数据类型为:image

    8.管理员权限控制。

    管理员信息表中权限字段保存一个字符串,拥有该项权限则在字符串相应位置保存为1,没有该项权限为0。在管理员登录时判断权限,启用或禁用相应的菜单项。

    9.信息分类。

    如客户分类分为:软件客户、网站客户、合作客户等。如果数据量不是太大,可不用单独建立分类表,在添加的时候,客户类型。可用ComboBox,在Form加载时检索数据库中已有的客户类型填充到ComboBox中。这样可选择已有客户类型,也可以添加新的客户类型。

    10.数据库安装。

    不必集成在安装包中,可单独写一个WinForm程序来收集连接服务器的信息(服务器地址、数据库名、用户名、密码等),并执行数据库生成的脚本来建立数据表,视图,存储过程、索引等。
    读取保存数据库脚本文件的代码:

            public static string ReadDBScript(string fileName)
            {
                StreamReader sr 
    = new StreamReader(fileName);
                
    return sr.ReadToEnd();
            }

    注意:数据库生成的脚本必须把"GO"去掉,否则执行时报错。

    11.安全控制。

    由于是网络版系统,因而安全性要考虑周全。数据库连接字符串加密保存在配置文件中。为了防止软件XCopy到其它机器中,可以取机器的硬件(如硬盘、网卡、CPU)序列号的一部分再加上自己的私有密钥作为连接字符串的加密密钥(八位ASCII),确保密钥的私密性、每机器唯一性。

    (1)取得机器CPU的ID的前八位作为密钥:

            public static string GetProcessID()
            {
                
    try
                {
                    
    string str = string.Empty;
                    ManagementClass mcCpu 
    = new ManagementClass("win32_Processor");
                    ManagementObjectCollection mocCpu 
    = mcCpu.GetInstances();

                    
    foreach (ManagementObject m in mocCpu)
                    {
                        str 
    = m["ProcessorId"].ToString().Trim().Substring(08);
                    }
                    
    return str;
                }
                
    catch (Exception ex)
                {
                    
    return "zhenxing"//如果失败取默认的密钥
                }
            }

     (2)加密算法:

            public static string Encode(string data)
            
    {
                
    byte[] aKey = System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());
                
    byte[] aIV = System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());

                DESCryptoServiceProvider cp 
    = new DESCryptoServiceProvider();
                MemoryStream ms 
    = new MemoryStream();
                CryptoStream cs 
    = new CryptoStream(ms, cp.CreateEncryptor(aKey, aIV), CryptoStreamMode.Write);
                StreamWriter sw 
    = new StreamWriter(cs);

                sw.Write(data);
                sw.Flush();
                cs.FlushFinalBlock();
                sw.Flush();
                
    return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
            }

     (3)解密算法:

            public static string Decode(string data)
            
    {
                
    byte[] aKey = System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());
                
    byte[] aIV = System.Text.ASCIIEncoding.ASCII.GetBytes(GetProcessID());

                
    byte[] Enc;
                
    try
                
    {
                    Enc 
    = Convert.FromBase64String(data);
                }

                
    catch
                
    {
                    
    return null;
                }


                DESCryptoServiceProvider cp 
    = new DESCryptoServiceProvider();
                MemoryStream ms 
    = new MemoryStream(Enc);
                CryptoStream cs 
    = new CryptoStream(ms, cp.CreateDecryptor(aKey, aIV), CryptoStreamMode.Read);
                StreamReader sr 
    = new StreamReader(cs);
                
    return sr.ReadToEnd();
            }

     (4)数据库连接字符串保存到配置文件:

            public static void SaveToConfig(string connStr)
            
    {
                XmlDocument doc 
    = new XmlDocument();
                
    string fn = "zxjay.exe.config";

                doc.Load(fn);

                XmlNodeList nodes 
    = doc.GetElementsByTagName("add");

                
    for (int i = 0; i < nodes.Count; i++)
                
    {
                    XmlAttribute att 
    = nodes[i].Attributes["key"];
                    
    if (att.Value == "SQLConectionString")
                    
    {
                        att 
    = nodes[i].Attributes["value"];
                        att.Value 
    = connStr;
                        
    break;
                    }

                }

                doc.Save(fn);
            }


    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zxjay/archive/2007/08/31/1766329.aspx

  • 相关阅读:
    2018.7.26笔记(变量的数据类型,if语句)
    id(),is 和 ==的区别,编码和解
    2018.7.31笔记(列表的基本操作)
    阅读与感悟如何高效学习
    说说设计模式 单例模式
    简单说说Java知识点 多线程
    阅读与感悟联盟
    阅读与感悟非暴力沟通
    简单说说Java知识点 HashMap
    MySQL知识树存储引擎
  • 原文地址:https://www.cnblogs.com/greatandforever/p/1526959.html
Copyright © 2020-2023  润新知