C# 中的动态创建技术
[转载]原文出处 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# 中的动态创建技术的更多相关文章
- Java中如何动态创建接口的实现
有很多应用场景,用到了接口动态实现,下面举几个典型的应用: 1.mybatis / jpa 等orm框架,可以在接口上加注解进行开发,不需要编写实现类,运行时动态产生实现. 2.dubbo等分布式服务 ...
- HTML中关于动态创建的标签无法绑定js事件的解决方法:.on()方法的 [.selector]
在前端页面的时候,会经常遇到用JavaScript动态创建出来的Button按钮或其他标签无法使用点击事件的问题.如下代码,使用jquery在body中动态创建一个class为demo的Button按 ...
- Python 中使用动态创建类属性的机制实现接口之后的依赖
我们在自动化测试中经常会需要关联用例处理,需要动态类属性: 推荐使用第二种方法: 创建:setattr() 获取:getattr() 两种,如何创建 类属性 loan_id # 第一种,创建 # 类名 ...
- Android中apk动态载入技术研究(2)android插件化及实现
了解了android中类载入的前期知识点后,来看看android中DexClassLoader详细的实现 详细载入流程例如以下: 宿主程序会到文件系统比方SD卡中去载入APK[1],然 ...
- WPF 中,动态创建Button,并使Button得样式按照自定义的Resource样式显示
第一步:自定义一个Button的样式 1.新建一个xaml文件,在其中自定义好自己的Resources 这个Resource 的根节点是 <ResourceDictionary xmlns=&q ...
- 在Delphi中如何动态创建dbf数据库(二)?
unit Form_ToChangCSVforDBFU; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics ...
- 在Delphi中如何动态创建dbf数据库(一)?
table2.Close; table2.Active:=false; table2.Exclusive:=true; table2.TableName:='h:\gzkd\sds'; table2. ...
- Android中ViewPager动态创建的ImageView铺满屏幕
ImageView imageView=new ImageView(context); imageView.setScaleType(ScaleType.FIT_XY);//铺满屏幕
- JavaScript DOM编程基础精华02(window对象的属性,事件中的this,动态创建DOM,innerText和innerHTML)
window对象的属性1 window.location对象: window.location.href=‘’;//重新导航到新页面,可以取值,也可以赋值. window.location.reloa ...
随机推荐
- 关于django过滤器的使用
最近项目中要做分类筛选,其实已经做了这个功能,但是有一个字段是MultiSelectField类型,包含多个值,用户提交的数据是单个值,无法查询出结果, 所以用到了自定义过滤 原代码 class In ...
- Effective STL 学习笔记: 多用 vector & string
Effective STL 学习笔记: 多用 vector & string 如果可能的话, 尽量避免自己去写动态分配的数组,转而使用 vector 和 string . 原书作者唯一想到的一 ...
- USACO 5.3 Network of Schools
Network of SchoolsIOI '96 Day 1 Problem 3 A number of schools are connected to a computer network. A ...
- 修改linux系统编码
方法1: vi /etc/sysconfig/i18n 默认为: LANG="en_US.UTF-8"SYSFONT="latarcyrheb-sun16" ...
- CI框架中site_url()和base_url()的区别
背景:在使用CI框架的使用经常碰到跳转和路径方面的问题,site_url()和base_url()很容易混淆,下面来说说他们的区别! 假如你config文件里面的base_url和index_page ...
- 牛客练习赛3 F - 监视任务
链接:https://www.nowcoder.net/acm/contest/13/F来源:牛客网 题目描述
- ThreadLocal和ThreadLocalMap源码分析
目录 ThreadLocal和ThreadLocalMap源码分析 背景分析 定义 例子 源码分析 ThreadLocalMap源码分析 ThreadLocal源码分析 执行流程总结 源码分析总结 T ...
- @react-native-community/async-storage在Android上的手动link问题
PS C:\Users\linjin\Desktop\RN_APP> react-native link @react-native-community/async-storage error ...
- Python 递归删除非空目录(包括子目录以及文件)
Python的OS模块自带rmdir和removedirs函数用于删除目录,但是两者都不能删除非空目录,以下代码定义了一个函数 remove_dir 用于删除非空目录. #作者官网 http://ww ...
- JAVA 获取分行符
public static final String CR_LF = System.getProperty("os.name").startsWith("Windows& ...