[转载]原文出处  http://blog.csdn.net/baiyun789/article/details/6156694

                       第一部分 WinForm控件在窗体中动态居中创建、删除控件及对其赋值

一、以lable为例:

在Form中放一个控件,让其在启动和动态改变窗口大小时始终居中

intgLeft=this.Width/2-lable1.Width/2;  //this指Form

intgTop=this.Height/2-lable1.Height/2;

lable1.Location=newPoint(gLeft,gTop);

二、动态创建控件并找到或者删除控件

1、以Lable为例创建控件:

Labellbl=newLabel();

lbl.Name="lblNum"+m;

lbl.AutoSize=true;

lbl.BackColor=System.Drawing.Color.Transparent;

lbl.Font=newSystem.Drawing.Font("宋体",36F,System.Drawing.FontStyle.Bold,System.Drawing.GraphicsUnit.Point,((byte)(134)));

lbl.ForeColor=System.Drawing.Color.White;

lbl.Location=newSystem.Drawing.Point(lable1.Location.X-150,29);

lbl.TextAlign=System.Drawing.ContentAlignment.TopCenter;

lbl.Anchor=System.Windows.Forms.AnchorStyles.Top;//this.Controls.Add(lbl);

窗体中添加控件this.groupBox2.Controls.Add(lbl);    //groupBox2中添加控件

2、以Lable为例删除控件:

if(this.groupBox2.Controls.ContainsKey("lable2")==true)

{

  this.groupBox2.Controls.RemoveByKey("lable2");

}

3、找到控件并对其赋值

Control[]control=this.Controls.Find("lable1",true);

if(control.Length==1&&control[0]isLabel)

{

  (control[0]asLabel).Text=“hello”;

}

                              第二部分  组件事件的动态添加

  通常在写程序的时候,当要用到某些组件,采用的方法一般都是动态创建,用完以后就释放掉。Visual C#在程序运行的时候也可以动态创建组件,下面就结合一个程序例子来具体介绍如何用Visual C#动态生成组件。首先让我们了解一下,在动态创建组件的过程中要用到的一些概论和理论。

  一. Boxing (装箱)和Unboxing (出箱):

  在用Visual C#动态创建组件的时候,要涉及到二种数据类型变量的转换,这二种类型变量就是实值类型(Value Type)变量和参考类型(Reference Type)变量,而这种转换过程在Visual C#中被称为Boxing (装箱)和Unboxing (出箱)。其中把实值类型变量转换成参考类型变量就是Boxing (装箱);把参考类型变量转换成实值类型变量就是Unboxing (出箱)。那么什么是实值类型,说的简单些,就是我们平常使用的整型、布尔型、枚举型等,这些类型的变量就是实值类型变量了;所谓参考类型,在Visual C#中指的就是Object、Class、Interface、Delegate、String、Array等,他和实值类型最主要的不同之处就是,参考类型变量存放的是指向实体对象的指针,而实值类型变量却是实实在在地实体对象。在本文介绍的程序中,主要涉及的是出箱。具体的处理方法,在下面有着具体介绍。

  二. 程序设计中的关键步骤以及解决方法:

  文中软件主要功能是用通过窗体上的二个按钮来创建二个不同类型的WinForm组件--Button组件和TextBox组件,并在创建的同时为每一个组件的属性赋值,给每一个创建的组件也创建了事件。

  (1).如何在窗体上创建Button组件:

  其实用Visual C#创建一个组件是十分方便的,只用下列二行语句就可以完成了:

Button myButton = new Button ( ) ;//创建一个新的Button组件

this.Controls.Add ( myButton ) ;  //在窗体中显示此按钮

但此时创建的这个Button组件没有任何属性,并且也没有任何事件,在本文中介绍的程序中创建的Button组件,不仅有属性也有事件,下列语句就是本文程序创建Button组件源代码:

counter += 1 ;             //按钮数量计算器在每次按钮按动后加 "1 "

locY += this.btnAdd.Height + 3 ;    //对要产生的按钮的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加 "3 "

Button myButton = new Button ( ) ;   //创建一个新的Button组件

myButton.Name = "Button " + counter ;//设定他的名称和Text属性,以及产生的相对位置

myButton.Text = "按钮 " + counter ;

myButton.Location = new Point ( btnAdd.Location.X , locY ) ;

//为产生的新的Button组件设定事件,本文中为产生的按钮设定了三个事件

myButton.MouseEnter += new System.EventHandler ( this.btn_MouseEnter ) ;

myButton.MouseLeave += new System.EventHandler ( this.btn_MouseLeave ) ;

myButton.Click += new System.EventHandler ( this.btn_Click ) ;

//在窗体中显示此按钮

this.Controls.Add ( myButton ) ;

  程序不仅为每一个组件的属性都赋值,而且为每一个组件都创建了三个事件。细心的读者可能已经注意到,程序为每一个组件创建的事件的名称都是一样的。这样就有一个问题,如何在这一样的事件中,识别到底是哪个Button组件触发了事件。

(2).确定是哪个组件触发了事件:

  由于程序中为每一个创建的Button组件的事件都是一样的,要想正确处理这些组件的事件,就需要在事件触发的程序中判断到底是哪个组件触发了这个事件。这就需要用到上面所提出的装箱和出箱。我们知道Sender对象是一个参考类型变量,他存放的是指向触发当前事件实体对象的指针。要把他给转换成实值对象类型,通过下列语句就可以确定是哪个组件触发了当前事件, 其他事件可以仿照此事件的处理过程来处理。

private void btn_MouseEnter ( object sender , System.EventArgs e )

{

  Button currentButton = ( Button ) sender ;//出箱

  currentButton.BackColor = Color.Red ;//设定按钮的背景色

}

 

(3). 如何在窗体上创建TextBox组件:

  创建TextBox组件的过程和创建Button组件过程相类似,只是在创建的组件类型上面有一点区别,具体实现语句如下:

counter01 += 1 ;                    //文本框数量计算器在每次按钮按动后加 "1 "

locY1 += this.txtAdd.Height + 3 ;            //对要产生的文本框的纵坐标的相对位置是前一个产生按钮的相对位置的纵坐标加 "3

TextBox myBox = new TextBox ( ) ;            //创建一个新的TextBox组件

myBox.Name = "TextBox " + counter01 ;        //设定他的名称和Text属性,以及产生的位置

myBox.Text = "文本框 " + counter01 ;

myBox.Location = new Point ( txtAdd.Location.X , locY1 ) ;

myBox.Click += new System.EventHandler ( this.btn_Click ) ;      //为产生的新的TextBox组件设定事件,本文中为产生的文本框设定了一个事件

this.Controls.Add ( myBox ) ;                        //在窗体中显示此文本框

  此时细心的读者又会发现,为每一个TextBox组件创建Click事件和为Button组件创建的Click事件也是一样的,这样在Click事件中不仅要判断是哪个组件触发了事件,还要判断是那种类型的组件触发了事件,下面语句是实现这些判断地具体方法:

private void btn_Click ( object sender , System.EventArgs e )

{

   if ( sender.GetType ( ) == typeof ( Button ) )

  {

    Button control = ( Button ) sender ;

    MessageBox.Show ( control.Text + "被按动了! ");

  }

  else

  {

    TextBox control = ( TextBox ) sender ;

    MessageBox.Show ( control.Text + "被按动了! " ) ;

  }

}

  当然如果你也可以单独为TextBox组件创建Click事件。此时创建的事件语句可改为:

myBox.Click += new System.EventHandler ( this.txt _Click ) ;

下面是实现txt _Click ( )事件的程序代码:

private void txt_Click ( object sender , System.EventArgs e )

{

TextBox currentButton = ( TextBox ) sender ;

MessageBox.Show ( currentButton.Text + "被按动了! ");

}

三、 总结:

  通过上面介绍,不难看出,动态创建组件并不是一件很难的事情,难就难在为这个组件创建事件上面,因为这涉及到实值类型变量和参考类型变量的转换,这就是所谓的装箱和出箱的问题。当然在程序设计的时候,你不仅可以创建那些可见的组件,也可以创建那些不可见的组件,具体的实现方法和本文中的方法类似。

C# 中的动态创建技术的更多相关文章

  1. Java中如何动态创建接口的实现

    有很多应用场景,用到了接口动态实现,下面举几个典型的应用: 1.mybatis / jpa 等orm框架,可以在接口上加注解进行开发,不需要编写实现类,运行时动态产生实现. 2.dubbo等分布式服务 ...

  2. HTML中关于动态创建的标签无法绑定js事件的解决方法:.on()方法的 [.selector]

    在前端页面的时候,会经常遇到用JavaScript动态创建出来的Button按钮或其他标签无法使用点击事件的问题.如下代码,使用jquery在body中动态创建一个class为demo的Button按 ...

  3. Python 中使用动态创建类属性的机制实现接口之后的依赖

    我们在自动化测试中经常会需要关联用例处理,需要动态类属性: 推荐使用第二种方法: 创建:setattr() 获取:getattr() 两种,如何创建 类属性 loan_id # 第一种,创建 # 类名 ...

  4. Android中apk动态载入技术研究(2)android插件化及实现

    了解了android中类载入的前期知识点后,来看看android中DexClassLoader详细的实现     详细载入流程例如以下:     宿主程序会到文件系统比方SD卡中去载入APK[1],然 ...

  5. WPF 中,动态创建Button,并使Button得样式按照自定义的Resource样式显示

    第一步:自定义一个Button的样式 1.新建一个xaml文件,在其中自定义好自己的Resources 这个Resource 的根节点是 <ResourceDictionary xmlns=&q ...

  6. 在Delphi中如何动态创建dbf数据库(二)?

    unit Form_ToChangCSVforDBFU; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics ...

  7. 在Delphi中如何动态创建dbf数据库(一)?

    table2.Close; table2.Active:=false; table2.Exclusive:=true; table2.TableName:='h:\gzkd\sds'; table2. ...

  8. Android中ViewPager动态创建的ImageView铺满屏幕

    ImageView imageView=new ImageView(context); imageView.setScaleType(ScaleType.FIT_XY);//铺满屏幕

  9. JavaScript DOM编程基础精华02(window对象的属性,事件中的this,动态创建DOM,innerText和innerHTML)

    window对象的属性1 window.location对象: window.location.href=‘’;//重新导航到新页面,可以取值,也可以赋值. window.location.reloa ...

随机推荐

  1. Codeforces 988F Rain and Umbrellas(DP)

    题目链接:http://codeforces.com/contest/988/problem/F 题目大意: 有三个整数a,n,m,a是终点坐标,给出n个范围(l,r)表示这块区域下雨,m把伞(p,w ...

  2. 在VirtualBox虚拟机中安装Centos操作系统怎么与本地XShell远程连接

    问题: 在VirtualBox安装好了CentOS操作系统后,我们怎么才可以用XSell连接虚拟机中的CentOS呢? 答案: (1)在windows下用cmd--ipconfig查看VirtualB ...

  3. 【LOJ】#2072. 「JSOI2016」独特的树叶

    题解 干脆题解套题解好了 毕竟我的hash方法是抄小迪的 https://www.cnblogs.com/RabbitHu/p/9165770.html 小迪太巨了%%% 之前模数是八位的WA了几个点 ...

  4. USACO 6.4 Electric Fences

    Electric FencesKolstad & Schrijvers Farmer John has decided to construct electric fences. He has ...

  5. Redis的安装与部署(CentOS6.5)

    一.下载安装包 wget http://redis.googlecode.com/files/redis-2.4.5.tar.gz 二.编译源程序 tar -zxvf redis-2.4.5.tar. ...

  6. scp和rsync的区别和常用参数

    一.scp 命令 1.scp 是 secure copy 的缩写,用于远程的文件的复制. 2.参数: -r: 递归复制整个目录. 3.实例: scp /home/space/music/1.mp3 u ...

  7. c++ 栈(顺序表)

    栈可以用顺序表(数组)也可以用链表来储存内容,本文采用顺序表(数组)来保存内部元素.代码如下:  1 #include <iostream> 2 using namespace std; ...

  8. 使用Retrofit2调用HTTP API

    前言 Retrofit会将你的HTTP接口调用转换为java的interface,你不必去实现这个接口,交给Retrofit来创建动态代理. 首先,贴上官网和Javadoc. 官网上的例子 加依赖,下 ...

  9. Bzoj1018/洛谷P4246 [SHOI2008]堵塞的交通(线段树分治+并查集)

    题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内 ...

  10. poj2676(数独)

    也是一个简单剪枝的dfs.记录所有为0的位置,依次填写,当发现某个空格可选的填写数字已经没有时,说明该支路无效,剪掉. 不算是一个难题吧,但是还是花了不少时间,问题主要出在细节上,行列坐标反了.3乘3 ...