关于C#自动生成的代码

大家想必都知道C#中因为用到很多控件在其事件里会生成一些代码。我想知道这么代码能不能改动,如果能,该注意什么?如果不能,那么我要手写代码来起到那些生成代码的作用的话,这些代码该怎么写,该注意什么?请高手指教举例说明。谢谢!

可以改动,你说的是:Form1.Designer.cs 这里面的自动生成的代码吧?
这里面只是将空间初始化,然后付给他默认值,比如控件所在位置之类的。
类似这些:
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.textBox3 = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.textBox4 = new System.Windows.Forms.TextBox();
this.label4 = new System.Windows.Forms.Label();
this.textBox5 = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(53, 12);
this.label1.TabIndex = 0;
this.label1.Text = "认证码:";

如果你要手写代码的话,基本不会这么去写。大多是在用到的时候才去写,这部分是在窗体被初始化的时候就加载的,你也可以在使用的时候手动创建,比如点击一个按钮,就在某个位置显示一个文本框:

private void button1_Click(object sender, EventArgs e)
{
TextBox tb = new TextBox();
tb.Size = new System.Drawing.Size(20,160);
tb.Location = new Point(100,100);
tb.Text = "默认值";
this.Controls.Add(tb);
}

以上就是动态的创建一个文本框,大小为 20 × 160 像素,位置在 横竖坐标都是 100 的位置,文本内容是 ”默认值“ 的文本框。最后 this.Controls.Add(tb); 就是将它添加到窗体上。

手写代码就是这样的,当然,你也可以动态的绑定事件。
只要遵照一个原则就可以完全自己手写了,就是先构造后使用就行了。
其他的就是注意一下,控件作用域的问题了,比如以上代码,在想拿到那个文本框的值的时候,只能在 button1_Click 的作用域中写(注:当然你也可以用窗体的控件查找方法在任何位置获得。)
如果放到 From 的直接作用域下,那么在整个类里面都可以直接使用。
温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-04-07
前段时间在CNBLOGS上面看到好多人谈论代码自动生成。这里所谓的代码自动生成是指自动根据数据库的内容身成数据访问存储过程以及对应的C#代码。比较典型的有CodePlus等(我最早看到的类似工具是DBHelper,大概是在CodeProject上,记不清楚了。功能强大而且完全开源)。这些代码自动生成工具确实会帮助我们减少代码编写的麻烦,提高工作效率。不过,我在这里还是想对“代码自动生成”发表一下我的看法:一、代码自动生成的言外之意是先有数据库再编代码 先设计数据库再根据数据库编写程序,很多人(包括我在内)都喜欢这样开发程序。因为这种开发模式似乎很对口味。不过问题也就随之而来了。首先,数据库的设计方案是根据业务方案而来的,通常要进行完业务流程分析后进行数据流程分析,然后建立数据字典给出数据库设计方案(传统的管理信息系统分析于设计方式)。在没有充分进行业务流程分析的情况下就开始数据库的设计是一项很危险的事。其次,我们使用的数据库通常是关系型数据库,而业务分析通常对应实体模型,为了更好的通过关系模型描述实体模型,数据库设计通常包括这么几个阶段:需求分析,分析业务流程以及数据库流程 概念设计,包括局部设计以及集成设计反复迭代,给出E-R图(实体-关系图) 物理设计,包括确定数据库物理结构、字段方案、约束条件、索引等等,建立物理模型 数据库实施,通过DDL建立数据库从分析的阶段上来看,也应当是先有实体而后有数据库。像Delphi 8中的ECO,在设计过程中首先进行对象的设计,然后通过Persist保存对象(可以存成XML,也可以存储成关系数据库)。很多人(包括我在内)喜欢先设计数据库的根源在于过于看重编码而轻视了分析流程。导致一旦数据库底层发生变化(这是很可能的),所有上层内容,包括存储过程、O-R代码、业务对象乃至表现层都会发生变化。代码的自动生成缓解了写代码的压力,但没有从根源上解决问题。软件开发的“依赖倒置原则”要求我们依赖于抽象而尽可能避免依赖于具体。在这里我们可以利用这种思想,将“抽象”提取出来。而最有可能担当“抽象”角色的就应当是“业务实体”本身。虽然客户需求的频繁变更倒置业务实体本身会发生变化,但是,这比依赖于数据库稳定的多。陈震军的《典型的分层、接口和工厂的写法》描述的微软宠物商店的数据库设计,其中的抽象层定义了业务实体接口。一旦业务实体发生变化,两条并行工作可以同时进行:一是根据业务的实体的变化向下修改数据库;二是根据抽象业务实体接口向上修改商业逻辑以及界面等等。如果没有这层抽象,恐怕只能根据业务实体的变化调整数据库,然后从数据库开始修改数据访问层、实体层、商业逻辑层直到标识层。相比之下还是第一种做法好一些。(这只代表个人观点,欢迎大家讨论)因此,所谓自动代码生成是根据关系模型生成实体模型呢还是根据实体模型生成关系模型,顺序问题值得讨论。
二、代码自动生成真的起到应有的作用了吗? 抛开O-R还是R-O问题,单纯从代码生成的角度来看,目前我看到的几种方案千篇一律,尤其是更新,生成的更新代码基本上没有抛开这个模式:UPDATE ... SET ... WHERE 关键字段=.... AND 其它字段=....数据库的更新如果真的这么简单就好了。不要忘记,现有的离线数据访问模式虽然提高了数据库的使用效率,但也带来了一系列的问题,其中最重要的一条就是并发操作(解决更新冲突问题)。并发操作的表现形式包括丢失的修改、不可重复读、读脏数据等(数据库原理里面有详细的说明以及解决对策),可到了代码自动生成这里,似乎这些并发问题根本不会出现。就拿丢失的修改来说:T1、甲售票员读出机票余额 16,存入本地缓存;
T2、乙售票员读出机票余额 16,也存入本地缓存;
T3、甲卖出一张,更新数据库 16-1 =15;
T4、乙也卖出一张,更新数据库 16-1 =15。这时候发现数据库中有15张票,而实际卖出了2张票。为了检测出并发异常,应当在更新时检测是否有数据库被其它人更改过。实现手段就是在UPDATE命令的WHERE子句中增加条件,判断数据是否还是当时读入数据时的数据。比如上面的问题在更新时应当写成:UPDATE ... SET Ticket=15 WHERE 关键字段=... AND Ticket=16其中后面的Ticket=16就是用来保护并发冲突的。16是当时读入数据的原始值。而在CNBLOGS中我看到的代码自动生成工具,没有人考虑这些更新问题,也没有人考虑保留原始数据,而是将这些问题一并推给了DataSet对象。不知道用这些工具生成的代码是否真可以使用?Visual FoxPro很早就把更新中WHERE短语生成策略考虑进来了。在VFP视图更新策略中,VFP(实际上Delphi也提供了类似的功能)提供了以下几种WHERE短语生成策略:关键字 关键字和可更新字段 关键字和已更新字段 时间戳虽然不能涵盖所有策略,但不失为一种好的解决方案。
三、更新成功后的后续操作怎么办? 如果再退一步,抛开一、二两个问题,更新真的可以成功。那么看下面的例子:有张表有三个字段:学号、姓名、年龄。一个人更新了年龄后,我更新了姓名(使用UPDATE Student SET Name = "aaa" WHERE id = 1 )。由于使用了离线数据库访问方式,这时候我不知道年龄也变了。正常情况下,在更新完成后要将数据库中的数据与目前缓冲中的数据库做一个同步,也就是说重新读入一次数据(在不同的应用系统中,这一步可能不是必须的)。但在自动生成代码的工具中没有人提供这种选项。
总结 上面就是我对代码自动生成工具的一些看法。随时欢迎大家讨论、批评、指正。
第2个回答  2013-04-07
如果你会托管和事件的话,再看那些代码,就会很简单。例:using System;namespace MyCollections
{
using System.Collections;
public delegate void ChangedEventHandler(object sender, EventArgs e);
public class ListWithChangedEvent : ArrayList
{
/* 声明一个事件,名称为Changed,并指明用ChangedEventHandler作为委托
当触发Changed事件时,可以通过ChangedEventHandler这个委托进行事件处理*/
public event ChangedEventHandler Changed; public event ChangedEventHandler Added; protected virtual void OnChanged(EventArgs e)
{
/* 事件调用: (调用事件的语法和调用方法类似,直接使用事件的名称,并传入事件的参数就可以了)
*
* 先判断是否有对象将委托与该事件关联,
* 如果没有对象将委托与事件关联,则委托的事件为null。
* 调用事件时先检查是否为null,如果不为null,再调用该事件。
* ※其实也可以理解为事件Changed当使用+=之后,Changed被赋值了(即被关联了委托ChangedEventHandler)
* ※同时由于委托指向了方法,因此当事件Changed发生时,被指向的方法也就可以被调用了。
*/
if (Changed != null)
Changed(this, e);
}
protected virtual void OnAdded(EventArgs e)
{
if (Added != null)
Added(this, EventArgs.Empty);
}
/* 当调用Add,Clear或者set数组的时候,就会调用OnChanged方法,而OnChanged方法中调用了Changed事件,
* 所以也可以说当调用如下的方法时调用了Change事件 */
public override int Add(object value)
{
int i= base.Add(value);
OnAdded(EventArgs.Empty);
return i;
} public override void Clear()
{
base.Clear();
OnChanged(EventArgs.Empty);
}
public override object this[int index]
{
set
{
base[index] = value;
OnChanged(EventArgs.Empty);
}
}
}
}namespace TestEvents
{
using MyCollections;
class Test
{
public static void Main()
{
ListWithChangedEvent list = new ListWithChangedEvent();
list.Added += new ChangedEventHandler(ListAdded);
/*
* 用+=将事件和委托关联在一起,使用-=解除关联。一旦建立起这种关联,委托就可以调用事件发生时处理的方法。
* 事件Changed和委托ChangedEventHandler关联在一起,并指明当事件发生时,调用参数中指明的方法ListChanged。
* 这样,ChangedEventHandler就知道,当对象的状态改变时,就调用Changed事件,调用Changed事件时就执行ListChanged这个方法。
*/
list.Changed += new ChangedEventHandler(ListChanged);
//以上的一步可以分解成如下二步:
//ChangedEventHandler a = new ChangedEventHandler(ListChanged);
//List.Changed += a;
list.Add("item 1");
list[0] = "item 2";
list.Clear();
list.Added -= new ChangedEventHandler(ListAdded);
list.Changed -= new ChangedEventHandler(ListChanged);
}
private static void ListChanged(object sender, EventArgs e)
{
/* 事件处理方法的参数类型和个数必须和delegate类型定义的一致,不过参数的名称可以相同也可以不同 */
Console.WriteLine("Changed or Cleared");
}
private static void ListAdded(object sender, EventArgs e)
{
Console.WriteLine("Added");
}
}
}
第3个回答  2013-04-07
可以改动,跟普通代码没什么区别。从2005开始IDE中实现了C#部分类的概念,也就是类可以用Partial修饰,多个Partial修饰的类同名的,编译时自动合并成一个类,自动生成的代码一般放在你的类名.Design.cs中,到那个文件中修改就可以了。没什么需要特别注意的,自动生成的代码一般是先初始化一个UI的实例,然后设置位置等属性,按钮之类的再加上事件处理委托(event+=)。
第4个回答  2013-04-07
控件自动生成的代码内容是静态方法设定控件的属性资料,保存在.designer.cs文件中。如果LZ学过Java,可以模仿Java的方式动态编写GUI控件,它的好处是可以安排控件布局,避免静态方式的死板和不方便,这样的程序,就不会有自动生成代码。如果要修改代码,则按照VS的提示类型输入需要的属性数据,要添加事件则在event属性中写+=事件方法即可。
相似回答