正在加载...

.net事件机制实例

三月 31st, 2009

//基类定义事件,并定义,何时触发这个事件
    public class MySetting
    {
        public event EventHandler SayHi;
        public MySetting()
        {
        }
        public void sayhi()
        {
            SayHi(this, null); 
        }
    }
    //派生类,将事件和它的处理函数绑定到一起,使用继承
    public class Settting1 : MySetting
    {
        public Settting1()
        {
            this.SayHi += new EventHandler(Settting1_SayHi);
        }
        public void Settting1_SayHi(object obj, EventArgs e)
        {
            MessageBox.Show("Sayhello");
        }
    }
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
         //   Application.Run(new Form1());
            Settting1 hi = new Settting1();
            hi.sayhi();
        }

    //组合类,实例化一个定义了事件的成员变量,然后绑定它的事件到相应处理函数
    public class Setting2
    {
        public MySetting set = new MySetting();
        public Setting2()
        {
            set.SayHi += new EventHandler(Settting2_SayHi);
        }
        public void Settting2_SayHi(object obj, EventArgs e)
        {
            MessageBox.Show("This is from hello 2");
        }
    }
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
         //   Application.Run(new Form1());
            Setting2 hi2 = new Setting2();
            hi2.set.sayhi();
        }

DotNet 数据库操作(一)基础

三月 28th, 2009

DotNet 数据库操作(一)基础

1. DataTable

DataTable是在内存中保存的一张二维表格,和数据库的关系图相对照。相比较DataSet用来执行数据库的操作,DataTable更多的,可以自定义一个DataTable作为dataGrid、DataList等的数据源。

常用的操作:

1)添加列

dt.Columns.add(string, Type)

2)添加行

DataRow dr = dt.NewRow();

dr["Name"] = "Jon";

dt.Rows.Add(dr);

或者

dt.Rows.Add(new object[] {"1", "st"})

2. SqlCommand

OleDbConnection odConn = ...

odConn.Open();

OleDbCommand cmd = odConn.CreateCommand(); 使用odConn创建一个Command

cmd.CommandText = "Select * From [Sheet1$]";  #执行的Sql文本,和Parameters平行

OleDbDataReader reader = cmd.ExecuteReader();  #使用DataReader从Command中读取数据

cmd.ExecuteNonQuery();  #执行无返回值的Sql

cmd.CommandType = CommandType.StoredProcedure/ Text  #使用存储过程,Sql语句两种方式执行

cmd.Parameters,cmd.CreateParameter() #Command的参数

odConn.Close()

3. SqlDataAdapter

可以直接执行Sql语句,并且将查询的结果装在DataSet中返回。DataSet就像运货的车,装载数据。

ds = new DataSet();

SqlConnection con = ...

con.Open();

SqlDataAdapter adapter = new SqlDataAdapter(sql, con);  #创建一个适配器访问数据库

int ret = 0;

ret = adapter.Fill(ds); #将返回值填充到DataSet中

con.Close();

4. SqlDataReader

使用DataAdapter的方式,可以很容易的执行sql语句,并且所有的结果都保存在DataSet中,方便读取。

使用SqlDataReader,可以获得执行结果的更详细的信息。例如获取一个保存有列的元数据的DataTable(2005)。返回每一列的列名等。

DataReader类似于Java的Iterator的方式读取数据。

while(reader.read())

object v = reader.getValue(index)

5. System.Data包

主要包含:

Odbc

SqlClient 可以访问微软的MSSql

SqlTypes 定义了一些数据类型等,在数据库端使用

OleDb 可以访问Office,如Access,Excel,全文索引数据库

信用卡利息计算方法

三月 27th, 2009

     信用卡一般有免息期,超期一毛不还要交利息且影响信用,超期最低还款要交利息,但不影响信用。最开始以为利息计算方法是:超期未还的金额 * 万分五 * 天数。

    下面是援引招商银行官方网站的利息计算方法

上期对帐单的每笔消费金额为计息本金,自该笔帐款记帐日起至该笔帐款还清日止为计息天数,日息万分之五为计息利率。循环信用的利息将在下期的帐单中列示。
举例说明:
● 假如您的帐单日为每月5日,到期还款日为每月23日;
● 4月5日银行为您打印的本期账单包括了您从3月6日至4月5日之间的所有交易账务;
● 假设本期账单周期内您仅有一笔消费,消费金额为人民币1000元,商户请款时间为3月30日;
● 您的本期账单列印“本期应还金额”为人民币1000元,“最低还款额”为100元;
● 不同情况下,您的循环利息分别为:
1) 若您于4月23日前,全额还清1000元,则在5月5日的对账单中循环利息=0。
2)若您于4月23日当天,只偿还最低还款额100元,则5月5日的对账单的循环利息为17.85元,具体计算如下:

1000元×0.05%×24天(3月30日至4月22日)+(1000-100)元×0.05%×13天(4月23日至5月5日) 


        循环利息 = 17.85元

注意两点:

1. 如果有超期未还的账单,借的1000元从借款之日起就开始收利息,直到还款日。也就是说,免息期失效了。

2. 超期未还的账单,从还款日,到下次对账的时间,都被收利息。这是意料之中的。

-------

总算理解了为什么我会被收那么多利息。

使用JS做导航条

三月 26th, 2009

    之前研究如何用iframe的方式做一个导航条,希望在子页面中控制父页面中控件的样式,以失败告终,导航条也没有整出来。这次再想这个问题,其实用简单的js就搞定了。

   代码分为三个部分。

   1. 控件

   <table><tr><td id='media' onmouseover='this.className="bannerCurrentItem"' onmouseout='this.className="bannerItem"'>
   <asp:hyperlink id='urlmedia' runat='server'>医疗</asp:hyperlink></td>
   <td id=accumulationonmouseover='this.className="bannerCurrentItem"' onmouseout='this.className="bannerItem"'>
   <asp:hyperlink id=urlaccumulationrunat='server'>医疗</asp:hyperlink></td></tr><table>

   2. JS

function setStyle()
{
    var name = document.getElementById("lblProcess").innerText;
    document.getElementById(name).className = "bannerCurrentItem";
    document.getElementById(name).onmouseover = "";
    document.getElementById(name).onmouseout = "";
}

其中lblProcess是一个隐藏控件,用来显示需要设置的TAB名称。

将html的body onload事件绑定到这个函数。

   3. 后台绑定

if(Page.Request["Process"] != null)
    this.lblProcess.Text = Page.Request["Process"].ToString();
else
    this.lblProcess.Text = "medical";

this.urlmedical.NavigateUrl = "WflRightSetting.aspx?Process=medical";
this.urlaccumulation.NavigateUrl = "WflRightSetting.aspx?Process=accumulation";

----------

参考:http://hi.baidu.com/zhangwenbo2009/blog/item/3310a489af5505b40f24448d.html

创作是纠结

三月 22nd, 2009

    周末看《张艺谋的2008》,对里面的两句话感受至深。

    创作是纠结,是不断和自己过不去的过程。创新也是纠结,因为创新是无中生有的。你甚至不知道,最终会走到什么地方,达到什么样的高度。

    张艺谋是有自己思想的人,做到这一点很不容易。因为处在那个位置,你会不断地收到别人的一些新鲜想法,这个时候没有自己的想法,看到一个喜欢一个,最后可能就是一个大杂烩。在那个位置的人,必须视野是相当开阔的,别人说一个想法,然后你能够从自己的知识库中提取,这个想法有没有类似的出处,究竟是否创新。

------------

    程序员的生活与此类似。

    无中生有,从一个字符一个字符地堆砌起来。最开始是机器码,然后将一定的机器码序列组合成一些固定的形式,成为汇编语言。再上层,就是高级语言了,如C语言之类。这时的语言,已经有了固定的规则,程序员在这些规则下,构建作品。如果说,最底层的语言是一些方块的话,那么高级语言就像各种各样的积木,你可以用它们组合成一座大厦,当然,也可能中途就不堪重负,倒塌。用一个个积木去搭房子,仍然困难重重,所以有人将积木做成一个个的构件,出售给程序员。这时候程序员的工作要轻松很多了。因为构件已经将很复杂的积木组合封装在内部,不用和那些繁杂纠结了。

    创新也是纠结。我知道,最后的建筑会很美好,但是真正拿着那一大堆积木的时候,就无所适从了。你可能,不知道从哪里开始下手,或者,好不容易有个开头,没过三分钟,积木就垮了,崩溃了。然后面对散落的积木,又开始发呆。从哪里下手呢?

    然后你要学会把自己变成张艺谋,处在总导演的位置,有广阔的视野,有扎实的基础。知道哪一个积木应该放在什么位置,也知道堆积木有哪些种搭法,知道哪些搭法可能走向最后的成功。

    创作是纠结,所以需要不断地和纠结做斗争。

GTD小软件:NBMemopad

三月 22nd, 2009

(软件最初是自己使用,所以可能存在bug,:-)

GTD,get things done!简单的说,就是管理好你自己的时间!

生活中经常觉得无所事事,或者觉得时间过得飞快,但一无所获。实际上大多数时候都是因为没有规划好自己的时间所致。我对时间管理的理解是,做好每一天!它至少也是至多包含3个步骤: 

  1. 计划,想一想,你接下来该做些什么,然后用笔记录下来
  2. 执行,按照你的计划,开始做事,Get Things Done。让事情从你的计划本上抹除
  3. 回顾,回顾一天,做了哪些事情,有哪些收获

基于这样的理念,我制作了小软件,称之为NBMemopad,用于管理我自己的时间。这个软件,侧重于对每一天的时间管理,以及下一天的计划,和前一天的回顾。

下载地址:http://code.google.com/p/nbmemopad/downloads/list

个人博客:http://19850517.appspot.com

(..More)

建议不要升级IE8正式版

三月 20th, 2009

    昨天晚上,IE8已经正式发布,赶紧下了一个体验一下。感觉很不爽!

    1. 一个软件至少安装了半个小时,重启两次。而且,IE的安装是在系统重启之后,所以它安装完成之前,你是什么事情也别想做的。干等半个小时吧!邪恶!而且,一不小心发现安装程序安装时,还在连网,但我的电脑,上网前需要先连锐捷上网认证的。。。没办法,只好先从任务管理器中把锐捷启动起来。然后继续等待。

    2. 支付宝,淘宝,统统用不了。网页倒是可以打开,但问题是,你打开后输不了密码。光标根本就没办法定位到密码输入框。这该算IE的问题,还是算淘宝的问题?

    3. 兼容性。我一般上网都使用世界之窗,当然,世界之窗,用的夜市IE的内核。问题是,这次升级之后,我发现世界之窗有更多的输入框没法输入了。像工行的密码输入框等等。用IE8时,工行的密码输入框可以用。

    4. 支持搜索框搜索引擎的定制,但要先连上官网,然后才能添加自己的搜索引擎。不就是设置一个网址么,整这么麻烦。当然,和前面三个比起来,这只是小问题。

   

     综合以上,建议还是先别升级到IE8. 升级带来的那点性能提升,会被各种各样的折磨所消耗。

 

image

使用Python实现的移动代理

三月 18th, 2009

      考虑这样一个场景:在一台主机上执行的程序,现在需要被中止,然后迁移到另外一台主机上继续之前未完成的任务。我们称这种程序为移动代理。使用Python有以下几种方式实现代理的迁移:

      python程序执行任务。使用Pickle模块序列化正在执行的类。

dump(obj, file, version)  #obj需要持久化的对象

load(file)  #file存放序列化数据

     上述两个接口将对象序列化到文件中,也可使用使用dumps()和loads()这个版本,将直接序列化为字符串。远程主机可以直接从序列化文本中还原对象在之前主机内存中的格式。在传送序列化数据的同时,也可以将代理的module文件同时传送,方便接收方修改类。

      使用其他语言完成的可执行组件。将python作为胶水语言,使用外部组件的动态链接库。

      可以使用SWIG制作Python和计算组件的粘合剂,使得可以在Python中调用C/C++的组件。这一过程需要完成以下几个步骤:

l 完成组件的代码

l 编写SWIG的接口文件

l 生成python的module

l 生成可执行的动态链接库

l 在python中调用生成的module

C++的众多语言特性,例如预编译、类、继承、模板等都可以通过这种方式,在python中调用。

      对于其他的语言,如Java,C#等,都可以通过其他途径将之粘合起来。JPype是一个Java和Python之间的接口层,允许Python程序完全访问Java中的类。IronPython让Python可以访问.Net开发的程序。可以看出,Python具备很好的语言兼容性。

     使用Python来迁移代理,其实是一件很容易的事情,特别是和C++相比。

腾讯的财付通

三月 15th, 2009

      真是垃圾啊!

      在支付时,总提示这个莫名其妙的错误。我使用的世界之窗浏览器3.0

image

 

     重试了几次之后,都提供这个不知所云的错误。仔细检查下,发现没有登陆。点击登陆框登陆,这个速度倒是蛮快。再次输入财付通密码,仍然提示上面的那个“缺少签名参数”这个错误。

     image

      难道是浏览器问题?按说和世界之窗和IE都是同样的内核,不会出这样的问题呀!换我的IE试一下,登陆,再输入财付通密码。这次出了个靠谱点的提示。提示我密码错误!用一个红色的label标签,说我的密码错了!早说嘛!换了个密码,OK,支付成功。

      另外,这个提示密码错误的label,红色的文字有两行,但不能够完全显示,只显示一半!这个没有截到图。

.Net中的委托和事件

三月 15th, 2009

delegate,标准的翻译方法是:委托

它类似于函数指针,这个要你自己实际操作一遍,就会理解深刻了。否则,也是今天记得了,明天忘记。

而委托,是函数指针的升级版,是为了解决函数指针潜在的一些风险而引入的。

下面看一个实际的例子:

手头上有个项目,在验收时被指出注释的数量不够。怎么办?用脚本程序往源文件里加。可以加的注释包括:1. License版权声明,2. 注释/代码行数统计,3. 函数注释自动生成,4. 类注释自动生成。。。

这几类需求有个共同的特点,都需要对源文件遍历,区别只是遍历后对文本的处理方式不一样。这个时候可以给遍历函数传递一个函数对象(函数指针,委托),在遍历函数内部调用这个函数对象去处理文本。用这种方式,把遍历函数写好后就不用管了,专心的去写添加注释的函数,然后再main中向tranverse遍历函数中传递注释函数。

表面看来,上面的处理方法有些像Java中像接口,注释函数都去实现这个“函数对象”,这个函数对象跟接口一样,然后通过这个接口让注释函数跟遍历函数产生关系。

但实际上委托和接口还是有很大不同:

这个过程用C#的委托来实现。

delegate void CommentDelegate(string filename, bool isFolder);

public MyClass

{

/*为filename这个源文件添加类注释*/

  public static void classComment(string filename, bool isFolder)

{

      //。。。

}

/*统计源文件中的注释行数*/

public static void countComment(string filename, bool isFolder)

{

  //...

}

  public static void Main()

{

   CommentDelegate a, b;

   cc = new CommentDelegate(classComment);

   count = new CommentDelegate(countComment);

}

}

委托和Java接口的不同在于:

1. 一个是将函数作为参数传递,一个是将instance作为参数作为参数传递,后者用到运行期动态绑定。

2. Java中好像没有函数指针这个概念,而添加了匿名内部类这个概念,这样看来,让一个匿名内部类继承接口,和函数指针已经比较类似了。嗯,普通的接口继承也蛮像。

3. 委托,另外一个作用是为是gui编程中的事件作准备的。在C#中,所谓的事件是一种特殊类型的delegate,用event关键字标识。一图抵千言,画了个图:

 image

这里的ChangedEventHandle就是一个特殊的Delegate,他有两个参数,没有返回值。

解释一下几个过程:

1. 在写代码时候,将控件的事件(Changed)和事件处理函数(ListChanged)绑定起来。对于开发人员,只需要写这段绑定函数即可。在运行期间,C#的“虚拟机”会将这个事件添加到事件库。

2. 在用户点击按钮后,会释放一个Changed事件(触发的过程不用管它),一般来说,这段释放事件的代码页有.net Framework中的代码完成了。释放的事件会传递给虚拟机的事件仓库。

3. Event仓库收到事件后,会检查并调用具体的事件处理函数去处理这个事件。其中,事件的发送者保存在sender中,事件的参数保存在EventArgs中。

说这么多,其实只是为了解释事件和委托的内部运行机制,很多的事情,framework都为我们做好了。我们只需要从控件的属性面板中选择一个事件,双击它,然后去写写事件响应函数了。连“+=”这个绑定步骤都由vs IDE帮我们自动完成了。

google reader
bloglines
鲜果
有道
QQ邮箱
* 更多订阅本站方式请看 订阅帮助