微软最近发布了Net Framework 下的 Chart 控件,以来弥补.Net平台下一直没有一个官方的强悍的图表控件的遗憾。
该控件支持多种图表(2D和3D),如饼图,柱状图,曲线图,散点图,雷达图,面积图,股票图等,而且同时支持Winform 和 Asp.net。
但令人遗憾的是,微软目前放出的只是.Net Framework 3.5版本的,没有For .Net Framework 2.0的。
据知情人士透漏,该控件是微软收购的,来源于 www.dundas.com,for .net 2.0 的版本有,但是要 Money 的,鄙视一下Ms。
效果图:








下载地址:
来源:
按照我们中文的习惯,在日常使用中,对于周几的说法,都是 “星期?” 的格式, 而不是 Sunday, Monday, … 这种E文的形式。
.NET 里面对 星期几 的返回, 通常使用 DayOfWeek 这个enum的形式,返回的是 0 ~ 6 的数值,默认情况下 表示 周日 ~ 周六。
如果要返回中文习惯的星期几,只需做一个简单的转换:
////dt 是需要返回星期几的具体日期 ////下面的实现方式,是采用的默认每周的第一天是Sunday(星期日) public static string CnWeekDayName(DateTime dt) { string[] cnWeekDayNames = {"日", "一", "二", "三", "四", "五", "六"}; return "星期" + cnWeekdayNames[(int)dt.DayOfWeek]; }
SQLite 是目前比较流行的一个开源、免费的小型的Embeddable RDBMS(关系型数据库),用C实现,内存占用较小,支持绝大数的SQL92标准,个别不支持的情况,在这里说明
对各种语言的支持也比较不错,wrapper很多。
Google Gears 、Mozilla 和 Adobe AIR 都在使用sqlite,应该说明其还是很不错的
SQLite 的关键字列表,这里
支持的sql语法,在这里
在 .NET 里面使用 SQLite, 我这里使用的wrapper是 System.Data.SQLite,它只需要一个dll,接口符合ADO.Net 2.0的定义,性能也不错,NHibernate用的也是它,目前支持ADO.NET 3.5了,支持集成在 VS2005 和 VS2008里面,而且支持wince,是个亮点
因为符合ADO.NET的规范,所以使用方式,基本和 SqlClient, OleDb等原生的一致
using System.Data; using System.Data.SQLite; //... using (SQLiteConnection cn = new SQLiteConnection( "Data Source=Test.db3;Pooling=true;FailIfMissing=false") ) { //在打开数据库时,会判断数据库是否存在,如果不存在,则在当前目录下创建一个 cn.Open(); using (SQLiteCommand cmd = new SQLiteCommand()) { cmd.Connection = cn; //建立表,如果表已经存在,则报错 cmd.CommandText = "CREATE TABLE [test] (id int, name nvarchar(20))"; cmd.ExecuteNonQuery(); //插入测试数据 for (int i = 2; i < 5; i++) { cmd.CommandText = string.Format("INSERT INTO [test] VALUES ({0}, '中文测试')", i); cmd.ExecuteNonQuery(); } for (int i = 5; i < 10; i++) { cmd.CommandText = string.Format("INSERT INTO [test] VALUES ({0}, 'English Test')", i); cmd.ExecuteNonQuery(); } //读取数据 cmd.CommandText = "SELECT * FROM [test]"; using (SQLiteDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { while (dr.Read()) { Console.WriteLine("第{0} 条:{1}", dr.GetValue(0), dr.GetString(1)); } } } }
本篇,我们用到了COM引用,因为不使用COM引用的话,操作太过繁琐了 
一、 添加 COM 引用
在引用里,选择 COM 页, 找到 NetFwTypeLib , 确定即可
二、 引入命名空间
using NetFwTypeLib;三、 添加允许通过防火墙的例外程序
//创建firewall管理类的实例 INetFwMgr netFwMgr = (INetFwMgr)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwMgr")); //创建一个认证程序类的实例 INetFwAuthorizedApplication app = (INetFwAuthorizedApplication)Activator.CreateInstance( Type.GetTypeFromProgID("HNetCfg.FwAuthorizedApplication")); //在例外列表里,程序显示的名称 app.Name = "自定义"; //程序的决定路径,这里使用程序本身 app.ProcessImageFileName = Application.ExecutablePath; //是否启用该规则 app.Enabled = true; //加入到防火墙的管理策略 netFwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Add(app);
四、删除一个例外 列表 里的程序
INetFwMgr netFwMgr = (INetFwMgr)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwMgr"));
//参数为程序的绝对路径
netFwMgr.LocalPolicy.CurrentProfile.AuthorizedApplications.Remove(Application.ExecutablePath);日期时间的输出和显示,在日常应用中,是最普遍的了。因为不同的情况,我们通常需要将日期时间以各种不同的样式格式化后输出,而不是简单的显示。
日期时间、数字、货币等的格式,默认情况下是受操作系统的区域设置影响的,在程序里,就体现在 当前线程的culture上(Thread.CurrentThread.CurrentCulture),为了避免区域不同的影响,我们通常需要设置
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
虽然 System.DateTime 本身已经具有了不少现成的格式化输出,例如: ToLongDateString, ToShortTimeString, ToUniversalTime 等,但是却远远不能满足我们实际的需要,这就要用到了 DateTime.ToString,就要提到 DateTimeFormatInfo 了,见下面的 MSDN 说明:
|
格式字符 |
关联属性/说明 |
|---|---|
|
d |
|
|
D |
|
|
f |
完整日期和时间(长日期和短时间) |
|
F |
FullDateTimePattern(长日期和长时间) |
|
g |
常规(短日期和短时间) |
|
G |
常规(短日期和长时间) |
|
m、M |
|
|
r、R |
|
|
s |
使用当地时间的 SortableDateTimePattern(基于 ISO 8601) |
|
t |
|
|
T |
|
|
u |
UniversalSortableDateTimePattern 用于显示通用时间的格式 |
|
U |
使用通用时间的完整日期和时间(长日期和长时间) |
|
y、Y |
具体使用时的格式参见:
|
格式模式 |
说明 |
|---|---|
|
d、%d |
月中的某一天。一位数的日期没有前导零。如果该格式模式没有与其他格式模式组合,则指定“%d”。 |
|
dd |
月中的某一天。一位数的日期有一个前导零。 |
|
ddd |
周中某天的缩写名称,在 AbbreviatedDayNames 中定义。 |
|
dddd |
周中某天的完整名称,在 DayNames 中定义。 |
|
M、%M |
月份数字。一位数的月份没有前导零。如果该格式模式没有与其他格式模式组合,则指定“%M”。 |
|
MM |
月份数字。一位数的月份有一个前导零。 |
|
MMM |
月份的缩写名称,在 AbbreviatedMonthNames 中定义。 |
|
MMMM |
月份的完整名称,在 MonthNames 中定义。 |
|
y、%y |
不包含纪元的年份。如果不包含纪元的年份小于 10,则显示不具有前导零的年份。如果该格式模式没有与其他格式模式组合,则指定“%y”。 |
|
yy |
不包含纪元的年份。如果不包含纪元的年份小于 10,则显示具有前导零的年份。 |
|
yyyy |
包括纪元的四位数的年份。 |
|
gg |
时期或纪元。如果要设置格式的日期不具有关联的时期或纪元字符串,则忽略该模式。 |
|
h、%h |
12 小时制的小时。一位数的小时数没有前导零。如果该格式模式没有与其他格式模式组合,则指定“%h”。 |
|
hh |
12 小时制的小时。一位数的小时数有前导零。 |
|
H、%H |
24 小时制的小时。一位数的小时数没有前导零。如果该格式模式没有与其他格式模式组合,则指定“%H”。 |
|
HH |
24 小时制的小时。一位数的小时数有前导零。 |
|
m、%m |
分钟。一位数的分钟数没有前导零。如果该格式模式没有与其他格式模式组合,则指定“%m”。 |
|
mm |
分钟。一位数的分钟数有一个前导零。 |
|
s、%s |
秒。一位数的秒数没有前导零。如果该格式模式没有与其他格式模式组合,则指定“%s”。 |
|
ss |
秒。一位数的秒数有一个前导零。 |
|
f、%f |
秒的小数精度为一位。其余数字被截断。如果该格式模式没有与其他格式模式组合,则指定“%f”。 |
|
ff |
秒的小数精度为两位。其余数字被截断。 |
|
fff |
秒的小数精度为三位。其余数字被截断。 |
|
ffff |
秒的小数精度为四位。其余数字被截断。 |
|
fffff |
秒的小数精度为五位。其余数字被截断。 |
|
ffffff |
秒的小数精度为六位。其余数字被截断。 |
|
fffffff |
秒的小数精度为七位。其余数字被截断。 |
|
F、%F |
显示秒的小数部分的最高有效数字。如果该数字为零,则不显示任何内容。如果该格式模式没有与其他格式模式组合,则指定“%F”。 |
|
FF |
显示秒的小数部分的两个最高有效数字。但是,不显示尾随的零(两个零数字)。 |
|
FFF |
显示秒的小数部分的三个最高有效数字。但是,不显示尾随的零(三个零数字)。 |
|
FFFF |
显示秒的小数部分的四个最高有效数字。但是,不显示尾随的零(四个零数字)。 |
|
FFFFF |
显示秒的小数部分的五个最高有效数字。但是,不显示尾随的零(五个零数字)。 |
|
FFFFFF |
显示秒的小数部分的六个最高有效数字。但是,不显示尾随的零(六个零数字)。 |
|
FFFFFFF |
显示秒的小数部分的七个最高有效数字。但是,不显示尾随的零(七个零数字)。 |
|
t、%t |
在 AMDesignator 或 PMDesignator 中定义的 AM/PM 指示项的第一个字符(如果存在)。如果该格式模式没有与其他格式模式组合,则指定“%t”。 |
|
tt |
在 AMDesignator 或 PMDesignator 中定义的 AM/PM 指示项(如果存在)。 |
|
z、%z |
时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数没有前导零。例如,太平洋标准时间是“-8”。如果该格式模式没有与其他格式模式组合,则指定“%z”。 |
|
zz |
时区偏移量(“+”或“-”后面仅跟小时)。一位数的小时数有前导零。例如,太平洋标准时间是“-08”。 |
|
zzz |
完整时区偏移量(“+”或“-”后面跟有小时和分钟)。一位数的小时数和分钟数有前导零。例如,太平洋标准时间是“-08:00”。 |
|
: |
在 TimeSeparator 中定义的默认时间分隔符。 |
|
/ |
在 DateSeparator 中定义的默认日期分隔符。 |
|
% c |
其中 c 是格式模式(如果单独使用)。也就是说,若要单独使用格式模式“d”、“f”、“F”、“h”、“m”、“s”、“t”、“y”、“z”、“H”或“M”,请指定“%d”、“%f”、“%F”、“%h”、“%m”、“%s”、“%t”、“%y”、“%z”、“%H”或“%M”。 如果格式模式与原义字符或其他格式模式合并,则可以省略“%”字符。 |
|
\ c |
其中 c 是任意字符。照原义显示字符。若要显示反斜杠字符,请使用“\\”。 |
我们有时候,需要知道某个网络资源是否有效、可用,但是我们并不想打开或下载这个资源,因为这个资源可能很大(例如需要下载的某个文件)
一种行之有效的方式,就是利用HTTP头返回的状态码来确定资源的可用性;我们通常的WEB访问,使用的是 GET 和 POST, 这里使用的是 HEAD 方式
static bool IsWebResourceAvailable(string webResourceAddress) { try { HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(webResourceAddress)); req.Method = "HEAD"; req.Timeout = 1000; HttpWebResponse res = (HttpWebResponse)req.GetResponse(); return (res.StatusCode == HttpStatusCode.OK); } catch (WebException wex) { System.Diagnostics.Trace.Write(wex.Message); return false; } }
上面的函数中, webResourceAddress 是资源的地址,
如果资源可用,返回 true, 否则返回 false用httpwebrequest访问一个SSL类型的地址 https://xxxx 时,报错 “未能为 SSL/TLS 安全通道建立信任关系(Could not establish trust relationship for the SSL/TLS secure channel)”
查了下MSDN,找到了解决方法,SSL网站,连接时需要提供证书,对于非必须提供客户端证书的情况,只要返回一个安全确认即可。但是此方法的实现,在.NET 1.1 和 .NET 2.0 下是不同的,下面写出2个framework版本下的实现方法:
使用的命名空间:
using System.Net; using System.Net.Security; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates;
.Net 2.0
public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { //直接确认,否则打不开 return true; } private void button1_Click(object sender, EventArgs e) { ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult); HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri("https://zu14.cn/")); req.Method = "GET"; HttpWebResponse res = (HttpWebResponse)req.GetResponse(); //...正常使用了,和访问普通的 http:// 地址一样了
.Net 1.1
internal class AcceptAllCertificatePolicy : ICertificatePolicy { public AcceptAllCertificatePolicy() { } public bool CheckValidationResult(ServicePoint sPoint, System.Security.Cryptography.X509Certificates.X509Certificate cert, WebRequest wRequest, int certProb) { //直接确认 return true; } } private void button1_Click(object sender, EventArgs e) { ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy(); HttpWebRequest req = (HttpWebRequest)WebRequest.CreateDefault(new Uri("https://zu14.cn/")); req.Method = "GET"; HttpWebResponse res = (HttpWebResponse)req.GetResponse(); //...正常使用了,和访问普通的 http:// 地址一样了
在PictureBox加载图片时,能不能显示等待,加载完毕后再显示真正的图片
答案是肯定的,而且PictureBox对这个的支持也是很完美的。下面我给出一部分核心代码,完整的代码,请下载最后的例子
void Button1Click(object sender, EventArgs e)
{
//图片异步加载完成后的处理事件
pictureBox1.LoadCompleted += new AsyncCompletedEventHandler(pictureBox1_LoadCompleted);
//图片加载时,显示等待光标
pictureBox1.UseWaitCursor = true;
//采用异步加载方式
pictureBox1.WaitOnLoad = false;
//开始异步加载,图片的地址,请自行更换
pictureBox1.LoadAsync("http://www.zu14.cn/wp-content/uploads/2009/02/image14.png");
}
void pictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e)
{
//图片加载完成后,将光标恢复
pictureBox1.UseWaitCursor = false;
}
C#里面,虽然在 System.Drawing.Printing 这个namespace下,提供了一些对系统打印机的访问功能,但是,说实话是太弱了,对获取打印机的相关属性基本是无能为力的。
C#里面获取打印机的详细信息,常用的用2种方式:
- 使用 Windows API
- 使用 WMI
我这里使用的是WMI的方式,因为此方式,是采用了类SQL的方法,将windows的WMI管理信息,作为一种数据库的形态来提供的,使用起来比较顺手
.NET 里面对WMI的使用,是放在 System.Management 这个空间下的,要使用的话,需要先添加对 System.Management.dll 引用
具体代码如下:
string wmiSQL = "SELECT * FROM Win32_Printer"; ManagementObjectCollection printers = new ManagementObjectSearcher(wmiSQL).Get(); foreach (ManagementObject printer in printers) { PropertyDataCollection.PropertyDataEnumerator pde = printer.Properties.GetEnumerator(); while (pde.MoveNext()) { MessageBox.Show(pde.Current.Name + " : " + pde.Current.Value); //显示的是 属性名 : 属性值 的形式 } }
应该是一目了然了吧,嘿嘿
从 VS2005开始,VS自带的 WebBrowser控件,就已经相当友好了,可控性非常高了。
Winform 结合 WebBrowser 做UI开发,也是一种非常流畅的模式了, 微软的VS IDE 系列的安装程序, 基本都是这个模式的 
在使用WebBrowser做UI的时候,我们有时不希望里面的链接被用户点击,更不希望弹出烦人的脚本错误提示框,也不希望用户能点出右键的IE菜单,要做到这些,其实都是很easy地…
禁用错误脚本提示
禁用右键菜单
禁用快捷键
禁用超链接
超链接分为两种,一种是 当前窗口直接转向, 一种是 在新窗口中打开
当然窗口直接转向:
在新窗口中打开:
private void webBrowser1_NewWindow(object sender, CancelEventArgs e) { e.Cancel = true; }
做完上面的工作,基本就完工了,还有最后一点需要注意,那就是 Drag-And-Drop
大功告成,Just Enjoy It !!
timer ,顾名思义:定时器;在程序中,需要定期去做某件事时,timer通常都是我们的首选,因为timer确实简单易用
。
通常,我们使用timer时,只做两件事:
- 给 timer 指定一个 interval值, 该值是以 毫秒为单位的(但是准确度没有那么高
)。
我们这里,比如赋值 2000 (2秒)
2. 在 timer 的 tick 事件里,加入要做的事
private void timer1_Tick( object sender, EventArgs e ) { // dosomething(); }
一般情况下, 上面的就OK啦
就上面的例子, 假定 interval 设定为 2000(2秒)
而 dosomething() 耗时为 3 秒或更多,那会发生什么事情呢?
结果是 dosomething 执行结束后,并没有等待2秒,而是直接又执行了一次,重复下去,违背了我们的初衷。
下面的例子,可以在很大程度上解决上面的问题:
private void timer1_Tick( object sender, EventArgs e ) { timer1.Stop(); //先停止timer try { //dosomething(); } finally { timer1.Start(); //要做事情结束后,再开始计时 } }
这个应用,是用在 WinForm 中的TreeView
当TreeView启用checkboxes 方式的时候,当父节点选中的时候,它所有的子节点一起被选中;当父节点取消选择的时候,它所有的子节点也取消选择。
实现起来,非常简单,代码如下:
/// <summary> /// 假设treeview的name是 treeView1 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void treeView1_AfterCheck(object sender, TreeViewEventArgs e) { if (e.Node.Nodes.Count > 0) { foreach (TreeNode node in e.Node.Nodes) { node.Checked = e.Node.Checked; } } }
DataTable dt = new DataTable(); dt.Columns.Add("Name"); dt.Columns.Add("VV"); dt.Rows.Add(new string[] { "王一", "x" }); dt.Rows.Add(new string[] { "赵一", "z" }); dt.Rows.Add(new string[] { "王二", "y" }); dt.Rows.Add(new string[] { "赵二", "w" }); this.comboBox1.DataSource = dt; this.comboBox1.DisplayMember = "Name"; this.comboBox1.ValueMember = "VV"; this.comboBox1.AutoCompleteSource = AutoCompleteSource.ListItems; this.comboBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
上面的 AutoCompleteSource 是大家应该关注的一点,具体的值有9种选择,其中8种是可以研究一下的
在Http协议中,规定了同个Http请求的并发连接数最大为2. 这个数值,可谓是太小了。
而目前的浏览器,已基本不再遵循这个限制,但是Dot Net平台上的 System.Net 还是默认遵循了这个标准的。
从而造成了,在使用HttpWebRequset 或者 WebClient 利用多线程的方式,访问某个网站时,经常出现 连接被异常关闭 的错误,大大降低了效率。
这个限制的值,是可以自己设置或配置的。
System.Net.ServicePointManager.DefaultConnectionLimit 就是设置的地方。 可以根据实际情况,来设置这个值的大小,不过,建议不要超过1024,推荐为512,已经足够了。
当然,也可以直接在程序的 app.config中配置这个值。
此值设置后,只对以后发起的HTTP请求有效。
这是来自 CodeProject 的一个开源项目,作者提供了一个封装好的打印DataGridView的类,使用起来非常简单。
支持常见的各种打印设置和分页等、支持页眉、页脚,页码显示位置、字体设置等等……
由于.NET自带的打印功能,过于弱了,使用起来非常不方便。
我对这个类库进行了测试,对中文的支持也很完美
使用的例子代码:
DGVPrinter printer = new DGVPrinter(); printer.Title = "DataGridView 打印测试"; printer.SubTitle = "这是子标题"; printer.SubTitleFormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoClip; printer.PageNumbers = true; printer.ShowTotalPageNumber = true; printer.PageNumberInHeader = false; printer.PorportionalColumns = true; printer.HeaderCellAlignment = StringAlignment.Near; printer.Footer = "页 脚"; printer.FooterSpacing = 15; printer.PageSeparator = " / "; printer.PageText = "页"; printer.PrintPreviewDataGridView(dataGridView1);
真是非常的便捷!
demo代码:[c#打印gridview]
在做涉及到金额的内容时,通常是需要输出一个金额的大写形式,这是中国的传统哦,嘿嘿,同时也提高安全性。

实现人民币从小写到大写的方法有很多种,今天,我这里提供一种给大家共享
public static string Convert(decimal number) { bool NegativeFlag = false; decimal RMBNumber; CheckNumberLimit(number); RMBNumber = Math.Round(number, 2); //将?四?舍?五?入?取?位?小?数? if (RMBNumber == 0) { return "零?元?整?"; } else if (RMBNumber < 0) //如?果?是?负?数? { NegativeFlag = true; RMBNumber = Math.Abs(RMBNumber); //取?绝?对?值? } else { NegativeFlag = false; } string buf = ""; // 存?放?返?回?结?果? string strDecPart = ""; // 存?放?小?数?部?分?的?处?理?结?果? string strIntPart = ""; // 存?放?整?数?部?分?的?处?理?结?果? string[] tmp = null; string strDigital = RMBNumber.ToString(); tmp = strDigital.Split(cDelim, 2); // 将?数?据?分?为?整?数?和?小?数?部?分? if (RMBNumber >= 1m) // 大?于?时?才?需?要?进?行?整?数?部?分?的?转?换? { strIntPart = ConvertInt(tmp[0]); } if (tmp.Length > 1) //分解出了小数 { strDecPart = ConvertDecimal(tmp[1]); } else //没有小数肯定是为整 { strDecPart = "整"; } if (NegativeFlag == false) //是?否?负?数? { buf = strIntPart + strDecPart; } else { buf = "负" + strIntPart + strDecPart; } return buf; }
Console.WriteLine("¥12345.67 对应的大写金额是 :" + DeltaCat.Net.RMB.Convert(12345.67M));
demo代码[c#人民币小写转大写]
在做一些MIS系统,尤其是人事相关的系统时,通常会用到需要将用户的姓名,转成汉语拼音的情形。
我自己在做一个卫生系统的小东东的时候,就遇到了这个要求,现在,也把这个的实现分享出来,源代码来源网上,由于是很早收集的,原作者已不详,就不标注了。
我进行了一些优化和整合,核心代码如下:
/// <summary> /// 完整转换函数,输出全拼的结果 /// </summary> /// <param name="CnString">传入的中文字符串</param> /// <returns>转换出的拼音组合</returns> public static string FullConvert(string CnString) { byte[] btArray = new byte[2]; int cAscii = 0; short idx1, idx2; StringBuilder sbResult = new StringBuilder(); char[] tempCArray = CnString.ToCharArray(); for (int idx = 0; idx < tempCArray.Length; idx++) { btArray = Encoding.Default.GetBytes(tempCArray[idx].ToString()); if (btArray.Length == 1) sbResult.Append(tempCArray[idx]); else { idx1 = (short)btArray[0]; idx2 = (short)btArray[1]; cAscii = idx1 * 256 + idx2 - 65536; if (cAscii > 0 && cAscii < 160) sbResult.Append(tempCArray[idx]); else { for (int i = pyValueArr.Length - 1; i >= 0; i--) { if (pyValueArr[i] <= cAscii) { sbResult.Append(pyCharacterArr[i]); break; } } } } } return sbResult.ToString(); } /// <summary> /// 只输出首字母的组合 /// </summary> /// <param name="CnString">待转换的中文字符串</param> /// <returns>拼音首字母组合结果</returns> public static string CapitalCovert(string CnString) { StringBuilder sbTemp = new StringBuilder(); for (int i = 0; i < CnString.Length; i++) { sbTemp.Append(GetCnCharAreaCode(CnString.Substring(i, 1))); } return sbTemp.ToString(); }
使用也非常简单:
Console.WriteLine("输出汉字的全拼:"); Console.WriteLine(DeltaCat.Net.Cn2Py.FullConvert("三角猫")); Console.WriteLine("输出汉字的首字母组合:"); Console.WriteLine(DeltaCat.Net.Cn2Py.CapitalCovert("三角猫 @ 真U14.CN"));
demo代码:c#汉字转拼音
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Security; using System.Security.Cryptography; /*---------------------------------------------- * DES加密、解密类库,字符串加密结果使用BASE64编码返回,支持文件的加密和解密 * 作者: 三角猫/DeltaCat * 网址: http://www.zu14.cn * 转载务必保留此信息 * --------------------------------------------- */ namespace ZU14 { public sealed class DES { string iv = "1234的yzo"; string key = "123在yzo"; /// <summary> /// DES加密偏移量,必须是>=8位长的字符串 /// </summary> public string IV { get { return iv; } set { iv = value; } } /// <summary> /// DES加密的私钥,必须是8位长的字符串 /// </summary> public string Key { get { return key; } set { key = value; } } /// <summary> /// 对字符串进行DES加密 /// </summary> /// <param name="sourceString">待加密的字符串</param> /// <returns>加密后的BASE64编码的字符串</returns> public string Encrypt(string sourceString) { byte[] btKey = Encoding.Default.GetBytes(key); byte[] btIV = Encoding.Default.GetBytes(iv); DESCryptoServiceProvider des = new DESCryptoServiceProvider(); using (MemoryStream ms = new MemoryStream()) { byte[] inData = Encoding.Default.GetBytes(sourceString); try { using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write)) { cs.Write(inData, 0, inData.Length); cs.FlushFinalBlock(); } return Convert.ToBase64String(ms.ToArray()); } catch { throw; } } } /// <summary> /// 对DES加密后的字符串进行解密 /// </summary> /// <param name="encryptedString">待解密的字符串</param> /// <returns>解密后的字符串</returns> public string Decrypt(string encryptedString) { byte[] btKey = Encoding.Default.GetBytes(key); byte[] btIV = Encoding.Default.GetBytes(iv); DESCryptoServiceProvider des = new DESCryptoServiceProvider(); using (MemoryStream ms = new MemoryStream()) { byte[] inData = Convert.FromBase64String(encryptedString); try { using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write)) { cs.Write(inData, 0, inData.Length); cs.FlushFinalBlock(); } return Encoding.Default.GetString(ms.ToArray()); } catch { throw; } } } /// <summary> /// 对文件内容进行DES加密 /// </summary> /// <param name="sourceFile">待加密的文件绝对路径</param> /// <param name="destFile">加密后的文件保存的绝对路径</param> public void EncryptFile(string sourceFile, string destFile) { if (!File.Exists(sourceFile)) throw new FileNotFoundException("指定的文件路径不存在!", sourceFile); byte[] btKey = Encoding.Default.GetBytes(key); byte[] btIV = Encoding.Default.GetBytes(iv); DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] btFile = File.ReadAllBytes(sourceFile); using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write)) { try { using (CryptoStream cs = new CryptoStream(fs, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write)) { cs.Write(btFile, 0, btFile.Length); cs.FlushFinalBlock(); } } catch { throw; } finally { fs.Close(); } } } /// <summary> /// 对文件内容进行DES加密,加密后覆盖掉原来的文件 /// </summary> /// <param name="sourceFile">待加密的文件的绝对路径</param> public void EncryptFile(string sourceFile) { EncryptFile(sourceFile, sourceFile); } /// <summary> /// 对文件内容进行DES解密 /// </summary> /// <param name="sourceFile">待解密的文件绝对路径</param> /// <param name="destFile">解密后的文件保存的绝对路径</param> public void DecryptFile(string sourceFile, string destFile) { if (!File.Exists(sourceFile)) throw new FileNotFoundException("指定的文件路径不存在!", sourceFile); byte[] btKey = Encoding.Default.GetBytes(key); byte[] btIV = Encoding.Default.GetBytes(iv); DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] btFile = File.ReadAllBytes(sourceFile); using (FileStream fs = new FileStream(destFile, FileMode.Create, FileAccess.Write)) { try { using (CryptoStream cs = new CryptoStream(fs, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write)) { cs.Write(btFile, 0, btFile.Length); cs.FlushFinalBlock(); } } catch { throw; } finally { fs.Close(); } } } /// <summary> /// 对文件内容进行DES解密,加密后覆盖掉原来的文件 /// </summary> /// <param name="sourceFile">待解密的文件的绝对路径</param> public void DecryptFile(string sourceFile) { DecryptFile(sourceFile, sourceFile); } } }
使用的例子:
ZU14.DES des = new ZU14.DES(); des.IV = "abcd哈哈笑"; des.Key = "必须八位"; string es = des.Encrypt("在"); Console.WriteLine(es); Console.Write(des.Decrypt(es)); des.EncryptFile(@"d:\a.txt", @"d:\b.txt"); des.DecryptFile(@"d:\b.txt"); Console.ReadKey(true);OK了。





