怎样在不对控件类型进行硬编码的情况下在 C#vs 中动态添加控件
文章ID: 815780
最近更新: 2004-1-12
这篇文章中的信息适用于:
- Microsoft Visual C# .NET 2003 标准版
- Microsoft Visual C# .NET 2002 标准版
本文引用下面的 Microsoft .NET Framework 类库名称空间:
- System.Reflection
概要
本文分步介绍了如何在 Visual C# .NET 中向窗体动态添加控件和如何响应控件的事件。
返回页首
分步示例
此部分介绍如何创建一个项目来演示如何在 Visual C# .NET 中向窗体动态添加控件和如何响应控件的事件。
- 启动 Microsoft Visual Studio .NET。
- 在“文件”菜单上,指向“新建”,然后单击“项目”。
- 单击“项目类型”下的“Visual C# 项目”,然后单击“模板”下的“Windows 应用程序”。默认情况下,Form1 将添加到该项目中。
- 将下面的代码添加到“Form1 代码”窗口的顶部:
using System.Reflection;
- 从工具箱拖出两个“Button”控件和一个“ComboBox”控件,然后将这些控件放在 Form1 底部附近。您将动态地将这些控件添加到窗体顶部。
- 在“属性”窗口中,按照下面的方法更改这些控件的“名称”和“文本”属性:
控件 名称 文本属性 button1 btnAddControl 添加控件 button2 btnRemoveControl 删除控件 comboBox1 cboControlType 选择控件类型 - 粘贴下面的代码作为 Form1 定义的前几个语句:
TreeView DynTreeview;
TextBox DynTextBox;
ListBox DynListBox;
Control ControlObject; - 切换到“设计”视图,然后双击“Form1”以将插入点定位到“Form1_Load”事件的第一行。
- 将下面的代码添加到“Form1_Load”事件中:
this.btnAddControl.Click += new System.EventHandler(this.btnAddControl_Click);
this.btnRemoveControl.Click += new System.EventHandler(this.btnRemoveControl_Click);
cboControlType.Items.AddRange(new object[3]{"TreeView","ListBox","TextBox"}); - 将下面的代码粘贴到 Form1 的“Windows 窗体设计器生成的代码”区域:
private void AddControl(string ControlName, string ControlType)
{
System.Reflection.Assembly asm;
asm = typeof(Form).Assembly;
ControlObject = (System.Windows.Forms.Control)asm.CreateInstance(ControlType);
ControlObject.Name = ControlName;
ControlObject.Location = new System.Drawing.Point(20, 20);
this.Controls.Add(ControlObject); if (ControlType.EndsWith("TreeView"))
{
DynTreeview = (System.Windows.Forms.TreeView)ControlObject;
DynTreeview.Width = 200;
DynTreeview.Height = 120;
DynTreeview.Nodes.Add(new TreeNode("Root"));
DynTreeview.Nodes.Add("FirstChild");
DynTreeview.Nodes.Add("SecondChild");
DynTreeview.ExpandAll();
DynTreeview.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(DynTree_AfterSelect);
}
else if (ControlType.EndsWith("ListBox"))
{
DynListBox = (System.Windows.Forms.ListBox)ControlObject;
DynListBox.Width = 200;
DynListBox.Height = 120;
DynListBox.Items.AddRange(new object[3]{"Apples", "Banana", "Oranges"});
DynListBox.SelectedIndexChanged += new System.EventHandler(DynCtrl_Event);
}
else if (ControlType.EndsWith("TextBox"))
{
DynTextBox = (System.Windows.Forms.TextBox)ControlObject;
DynTextBox.Width = 200;
DynTextBox.Text = "Dynamically Added Textbox.";
DynTextBox.DoubleClick += new System.EventHandler(DynCtrl_Event);
}
} private void btnAddControl_Click(object sender, System.EventArgs e)
{
string CtrlType; if (!(ControlObject == null))
{
btnRemoveControl.PerformClick();
} if (cboControlType.SelectedIndex < 0)
{
MessageBox.Show("Select a Control Type to add.");
return;
} CtrlType = "System.Windows.Forms." + cboControlType.SelectedItem.ToString();
this.AddControl("myControl", CtrlType);
} private void DynCtrl_Event(object sender, System.EventArgs e)
{
if (sender.GetType().ToString().EndsWith("ListBox"))
{
MessageBox.Show("The item you selected is: " + DynListBox.SelectedItem.ToString());
}
else if (sender.GetType().ToString().EndsWith("TextBox"))
{
Clipboard.SetDataObject(DynTextBox.Text);
MessageBox.Show("The Text is copied to the clipboard.");
}
} private void btnRemoveControl_Click(object sender, System.EventArgs e)
{
this.Controls.Remove(ControlObject);
ControlObject = null;
} private void DynTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
MessageBox.Show("The Node you clicked on is: " + e.Node.Text);
} - 保存项目。
- 若要运行项目,请单击“调试”菜单中的“开始”。
- 在组合框中,单击“TreeView”作为控件类型,然后单击“添加控件”。您会注意到添加了一个新的 TreeView 控件。单击任何节点,测试 TreeView 的“AfterClick”事件。
代码讨论
- 在此示例中,ComboBox 控件包含一个要动态添加的控件类型的列表。您需要将此列表填充到窗体的 Load 事件中。
- 因为您在 Form1 定义的前面几个语句中声明了三个特定的控件对象,因此您可以在程序中分别使用这些控件对象的功能。通过声明特定的控件类型,您还可以在编程时访问 Microsoft IntelliSense。
- 在 btnAddControl_Click 事件处理程序中,检查以确定是否已加载了另一个控件。如果是,请删除现有的控件,然后添加在组合框中选定的新控件。还需要确保在组合框中作的选择有效。如果选择无效,程序将生成一个信息框,并退出事件处理程序而不继续处理语句。如果选择有效,则可以使用适当的参数调用 AddControl 方法。
- 在 AddControl 方法中,您已将 asm 声明为 System.Reflection.Assembly 类型。typeof(Form) 语句返回 Form 类型的类型对象。然后使用此对象的 Assembly 方法检索定义了 Form 类的程序集的实例。在程序集之后,将创建 asm 对象。您使用 asm 对象的 CreateInstance 方法和一个 ControlType 字符串参数创建了该控件的一个实例。在创建此控件后,您使用 this.Controls.Add 方法将其添加到当前的窗体。然后,通过使用 String 类的 EndsWith 方法,您检查作为第二个参数传递到此过程的控件的类型。根据控件类型,您在 if...else...if... 代码块中设置了控件的个别属性。您使用 += 操作符将动态添加的控件的特定事件连接到事件处理程序。对于 ListBox 和 TextBox 控件,您将 SelectedIndexChanged 和 DoubleClick 事件连接到 DynCtrl_Event 事件处理程序。对于 TreeView 控件,您使用了一个单独的事件处理程序 (DynTree_AfterSelect) 将此控件连接到 TreeView 控件的 AfterSelect 事件。
- TreeView 控件的事件处理程序要求一个与其他两个控件不同的签名。“DynTree_AfterSelect”事件处理程序的第二个参数的类型是“System.Windows.Forms.TreeViewEventArgs”;对于“DynCtrl_Event”事件处理程序,您使用了类型“System.EventArgs”。“System.Windows.Forms.TreeViewEventArgs”类型提供了附加的信息,如选定节点的属性。
参考
有关在控件类型是硬编码时在窗体上添加控件的更多信息,请访问下面的 Microsoft Developer Network (MSDN) Web 站点:
Adding Controls to Windows Forms http://msdn.microsoft.com/library/en-us/vbcon/html/vbtskaddingcontrolstoform.asp
有关事件处理程序的详细信息,请访问下面的 MSDN Web 站点:
Events and Delegates http://msdn.microsoft.com/library/en-us/cpguide/html/cpconeventsdelegates.asp
Keywords: kbhowtomaster kbwindowsforms kbide kbnamespace kbtreeview kblistbox kbprogramming kbctrlcreate kbforms kbbutton kbcombobox kbevent KB815780
怎样在不对控件类型进行硬编码的情况下在 C#vs 中动态添加控件的更多相关文章
- VC中动态添加控件
VC中动态添加控件 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态控件: 为了对照,我们先来看一下静态控件的创建. 放置静态控件时必须先建立一个 ...
- Android 在布局容器中动态添加控件
这里,通过一个小demo,就可以掌握在布局容器中动态添加控件,以动态添加Button控件为例,添加其他控件同样道理. 1.addView 添加控件到布局容器 2.removeView 在布局容器中删掉 ...
- WinForm中动态添加控件 出现事件混乱,解决办法记录。
还是在抢票软件中出的问题,我没点击一个联系人,要生成一排控件,其中有席别combobox这样的下拉框控件,会出现如下图所示的问题:问题描述:在代码中动态创建的控件,事件混乱了,一个控件触发了所有同类型 ...
- 结合ItemsControl在Canvas中动态添加控件的最MVVM的方式
今天很开心的收获: ItemsControl 中 ItemsPanel的重定义和 ItemContainerStyle 以及 ItemTemplate 三者的巧妙结合,在后台代码不实例化任何控件的前提 ...
- android 在布局中动态添加控件
第一步 final LayoutInflater inflater = LayoutInflater.from(this); 第二步:获取需要被添加控件的布局 final LinearLayout l ...
- MFC中动态添加控件----寻找多年的秘籍,吐血推荐
原文作者tianwaik 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态控件 为了对照,我们先来看一下静态控件的创建. 放置静态控件时必须先建立 ...
- winform导入导出excel,后台动态添加控件
思路: 导入: 1,初始化一个OpenFileDialog类 (OpenFileDialog fileDialog = new OpenFileDialog();) 2, 获取用户选择文件的后缀名(s ...
- Android 在程序中动态添加 View 布局或控件
有时我们需要在程序中动态添加布局或控件等,下面用程序来展示一下相应的方法: 1.addView 添加View到布局容器 2.removeView 在布局容器中删掉已有的View 3.LayoutPar ...
- jQuery EasyUI动态添加控件或者ajax加载页面后不能自动渲染问题的解决方法
博客分类: jquery-easyui jQueryAjax框架HTML 现象: AJAX返回的html无法做到自动渲染为EasyUI的样式.比如:class="easyui-layout ...
随机推荐
- APACHE KYLIN™ 概览
APACHE KYLIN™ 概览 Apache Kylin™是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc. 开发 ...
- std::vector
Vector Vectors are sequence containers representing arrays that can change in size. Just like arrays ...
- jquery通过val()取不到textarea中的值
小编定义了一个textarea控件,却无法根据id取到textarea对象并赋值. 经过实验,得出了原因.代码如下: <!DOCTYPE html> <html> <he ...
- mysql5.7.22 zip 版安装
2.将zip文件解压到本地,本文解压到如下目录:D:\softwares\mysql-5.7.14-winx64 3.新建一个配置文件(my.ini)用于配置字符集.端口等信息,用以覆盖原始的配置文件 ...
- 查看文件内容- 删除某个运行程序的所有进程-nohup后台执行程序
1 查看文件内容: tail -f test.txt 2 查看端口 netstat nlp 3 删除某个运行程序的所有进程 ps -ef|grep translateService.py|grep - ...
- MapReduce源码分析之Task中关于对应TaskAttempt存储Map方案的一些思考
我们知道,MapReduce有三层调度模型,即Job——>Task——>TaskAttempt,并且: 1.通常一个Job存在多个Task,这些Task总共有Map Task和Redcue ...
- IOS设计模式浅析之原型模式(Prototype)
原型模式的定义 “使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象”.最初的定义出现于<设计模式>(Addison-Wesley,1994). 简单来理解就是根据这个原型创建 ...
- Nginx区分PC或手机访问不同网站
近几年来,随着手机和pad的普及,越来越多的用户选择使用移动客户端访问网站,而为了获取更好的用户体验,就需要针对不同的设备显示出最合适的匹配,这样就是近年来流行的“响应式web设计”. 响应式web设 ...
- ThinkPHP -- 问题
@.nginx下,找不到页面,如果然nginx支持pathinfo模式 原文:http://www.leixuesong.cn/1418 把文章的配置拷贝了下.
- onload 和 onunload 事件
onload 和 onunload 事件会在用户进入或离开页面时被触发. onload 事件可用于检测访问者的浏览器类型和浏览器版本,并基于这些信息来加载网页的正确版本. onload 和 onunl ...