单个方法显示所有子窗体(使用反射)C#
winform 遍历所有子窗体的方法

winform 遍历所有子窗体的方法
通过遍历所有子窗体,可以方便地获取到窗体以及其子窗体的各种属性和控件信息。
在 Winform 中,可以使用以下方法:
1. 使用递归方法遍历所有子窗体
递归方法是遍历子窗体最常用和最方便的方法。
该方法通过在父窗体中遍历所有控件,然后递归调用自己来遍历子窗体。
```csharp
private void TraverseControls(Control control)
{
foreach (Control ctrl in control.Controls)
{
// 处理当前控件
Console.WriteLine();
// 递归处理子控件
TraverseControls(ctrl);
}
}
```
2. 使用窗体容器控件的 Controls 属性遍历所有子窗体
Winform 中的容器控件(例如 Panel、GroupBox 等)都有一个Controls 属性,该属性返回一个包含容器内所有控件的控件集合。
可以使用该属性遍历容器内所有子窗体。
```csharp
foreach (Control ctrl in this.Controls)
{
// 处理当前控件
Console.WriteLine();
}
```
需要注意的是,该方法只能遍历直接添加在窗体上的子控件,无法遍历窗体内嵌的容器控件。
通过以上两种方法,可以轻松遍历 Winform 程序中所有子窗体,从而实现各种操作。
C# 第6章 窗体、控件和组件

窗体的常用方法和事件
方法和事件名 说明
13
Close()方法
Hide()方法 Show()方法 Load事件
使窗体关闭,并释放资源;
使窗体隐藏,并不释放资源; 显示窗体; 加载窗体时处理的事件;
Click事件
Closing、Closed事件 GetFocus事件 Activated事件
鼠标单击窗体时处理的事件;
它还只是一个TextBox类型的变量而已,如果在InitializeCompon ent( )之前调用这个TextBox的属性或方法,就会出错。
6.1.3 窗体常用的属性
属性 Name BackColor ForeColor 含义 窗体的名称,代码中通过该属性来访 问窗体 窗体的背景色 窗体上文本的前景色 注意
C#中的InitializeComponent()方法
注意: InitializeComponent( )方法写在前面和后面是有区别的。
23
InitializeComponent( )方法是用来初始化窗体组件的,在Initializ
eComponent之前,窗体的各个控件还没有进行初始化,比如说
窗体上有一个TextBoxUserName,在InitializeComponent( )之前
19
20
6.1.2 窗体的创建、显示与隐藏
【例6-1】演示窗体的基本用法以及如何显示和关闭窗体。 部分运行效果如图:
C#中的InitializeComponent()方法
在每一个窗体生成的时候,都会针对于当前的窗体定义Initi alizeComponent()方法,该方法实际上是由系统生成的对于
3、如何隐藏一个打开的窗体 (1)隐藏当前窗体:this.Hide(); (2)隐藏其它窗体:Application.OpenForms["Form1"].H ide();
C#实现Winform间的数据交互的三种方法

C#实现Winform间的数据交互的三种⽅法使⽤.NET编写winform程序,⽐较常见的⼀种情况就是如何实现Form间的数据交互,下⾯就简单总结⼀下常见的⼏种数据交互⽅式:(1)修改⼦窗体的构造函数:简单地说就是通过修改⼦窗体Form的构造函数,如下所⽰:public Form2(string Para1, ArrayList List1, TextBox textBox1, Form Form1){InitializeComponent();}上⾯的例⼦中,为⼦窗体Form2添加了4个参数,分别是:字符串Para1,字符数组List1,⽂本控件textBox1和⽗窗体Form1,下⾯简单区分⼀下它们各⾃的特点:<1> 字符串:单向的值传递,在⼦窗体中不能通过修改此参数的值来间接改变⽗窗体中的数据。
<2> 字符数组:引⽤型传递,可以通过将⽗⼦窗体中不同的成员变量指向相同的数组,即可实现变更⼀⽅,同时更新对⽅的数据。
<3> 控件:引⽤型传递,可以通过修改该控件的数据来直接达到控制⽗窗体中该控件数据的⽬的。
<4> 窗体:这个最直接,直接将⽗窗体传递到⼦窗体中,我们可以⽅便地在⼦窗体中修改⽗窗体中所有授权为public的数据。
(2)给窗体添加属性或⽅法:获取或设置拥有此窗体的窗体。
若要使某窗体归另⼀个窗体所有,请为其 Owner 属性分配⼀个对将成为所有者的窗体的引⽤。
当⼀个窗体归另⼀窗体所有时,它便随着所有者窗体最⼩化和关闭。
例如,如果 Form2 归窗体 Form1 所有,则关闭或最⼩化 Form1 时,也会关闭或最⼩化 Form2。
并且附属窗体从不显⽰在其所有者窗体后⾯。
可以将附属窗体⽤于查找和替换窗⼝之类的窗⼝,当选定所有者窗体时,这些窗⼝不应消失。
若要确定某⽗窗体拥有的窗体,请使⽤OwnedForms属性。
我们可以通过下⾯的⽅式来确定这种从属的窗体关系:Form2 form = new Form2();form.Owner = this;form.ShowDialog();或者Form2 form = new Form2();form.ShowDialog(this);定了从属关系以后,我们就可以通过在Form的load事件中或者通过定义public的属性或者⽅法来彼此进⾏数据修改操作,简单操作如下:Form1 pareForm = (Form1)this.Owner;this.listData1 = pareForm.ListData2;(3)通过委托的⽅法:相对以上两种⽅法来说,这种⽅法可能较复杂⼀些,但基本思路是⼀样的,需要修改的地⽅如下:<1> 在Form2.cs中添加委托函数定义:public delegate void SendFun(string str);<2> 在Form2.cs中添加委托⽰例:public event SendFun SendToParent;<3> 在Form2.cs中添加⼀个按钮,并添加其事件如下:private void button1_Click(object sender, EventArgs e){if (Send != null){Send(this.textBox1.Text);}}<4> 在Form1.cs中添加⽅法RecvInfo()⽅法如下:private void RecvInfo (string str){textBox1.Text = str;}<5> 在Form1.Designer.cs中的InitializeComponent()⽅法中添加委托实例定义:this.myForm.Send += new Example3_Form2. SendFun (RecvInfo);通过上⾯五步操作,即可达到Form间的通信的⽬的。
c子窗体调用父窗体的方法

c子窗体调用父窗体的方法以C#子窗体调用父窗体的方法为题,我们来探讨一下如何在C#中实现子窗体与父窗体之间的方法调用。
在C#中,窗体是一个类,子窗体(子类)可以继承父窗体(父类),从而可以调用父窗体中的方法。
下面我们将介绍两种常见的子窗体调用父窗体方法的方法。
方法一:使用委托和事件委托和事件是C#中常用的实现事件机制的方式。
通过定义委托和事件,可以在子窗体中触发事件,并在父窗体中注册事件处理程序来响应事件。
在父窗体中定义一个委托和事件。
委托是一种类型,用于定义方法的签名。
事件是委托的实例,用于触发和处理事件。
```csharppublic delegate void MyEventHandler(string message);public event MyEventHandler MyEvent;```然后,在子窗体中触发事件。
```csharpprivate void button1_Click(object sender, EventArgs e){MyEvent?.Invoke("Hello from child form!");}```在父窗体中注册事件处理程序。
```csharpchildForm.MyEvent += ChildForm_MyEvent;private void ChildForm_MyEvent(string message){MessageBox.Show(message);}```这样,当子窗体中的按钮被点击时,子窗体触发事件,并传递一个消息给父窗体,父窗体接收到消息后弹出一个消息框显示该消息。
方法二:使用属性和方法调用除了使用委托和事件,还可以通过属性和方法来实现子窗体调用父窗体的方法。
在父窗体中定义一个公共的方法。
```csharppublic void ShowMessage(string message){MessageBox.Show(message);}```然后,在子窗体中调用父窗体的方法。
C#一个窗体调用另一个窗体的方法

{ InitializeComponent(); m_formA = this;
}
3、最后就可以在窗体B中调用窗体A中的方法了,但必须遵从以下调用格式: 例如:FormA.m_formA.buttonDirectionMove(sender, e, "left");
博客园 用户登录 代码改变世界 密码登录 短信登录 忘记登录用户名 忘记密码 记住我 登录 第三方登录/注册 没有账户, 立即注册
C#一 个 窗 体 调 用 另 一 个 窗 体 的 方 法
一个窗体调用另一个窗体的方法: 例如:窗体B要调用窗体A中的方法 1、首先在窗体A中将窗体A设为静态窗体 public static FormA m_formA; //设此窗体为静态,其他窗体可调用此窗体中的方法
格式:
C#利用反射,遍历获得一个类的所有属性名

命名空间:System.Reflection
程序集:mscorlib(在mscorlib.dll 中)
C#利用反射,遍历获得一个类的所有属性名,以及该类的实例的所有属性的值
总结:
对应某个类的实例化的对象tc, 遍历获取所有属性(子成员)的方法(采用反射):
Type t = tc.GetType();//获得该类的Type
//再用Type.GetProperties获得PropertyInfo[],然后就可以用foreach 遍历了
foreach (PropertyInfo pi in t.GetProperties())
{
object value1 = pi.GetValue(tc, null));//用pi.GetValue获得值
string name = ;//获得属性的名字,后面就可以根据名字判断来进行些自己想要的操作
//获得属性的类型,进行判断然后进行以后的操作,例如判断获得的属性是整数
if(value1.GetType() == typeof(int))
{
//进行你想要的操作
}
}
注意:
必须要设置了get 和set方法的属性,反射才能获得该属性
public int Pid
{
get { return pid; }
set { pid = value; }
}。
C#反射查看和调用程序集的类和方法
Console.WriteLine("数组不能为null,数组的长度也不能为,暂定返回值 为-1");
maxIndex = -1; return -1; } int max = array[0]; maxIndex = 0; for (int i = 1; i < array.Length; i++) { if (max < array[i]) {
System.Reflection.MethodInfo mi1 = ty.GetMethod("GetMaxNumber");
//调用实例化方法(非静态方法)需要创建类型的一个实例 object instanceObject = Activator.CreateInstance(ty); int maxIndex = -1; object[] parametersInfo = new object[] { new int[] { 8, 20, 15, 36, 1, 2 }, maxIndex };
Console.WriteLine("私有方法"); } } }
★类 Test1 源代码:
using System;
using System.Collections.Generic; using System.Text;
namespace TestClassLibrary {
class Test1 {
//当我们知道方法的类型是引用类型时(带有"&"表示引用类型) 如:System.Int32&,此时参数带ref或out修饰
//如果参数是输出参数(paras[k].IsOut==true),则参数的修饰 是out,否则是ref
【C#反射】Type的用法
// Assign the value zero to MyProp. The Property Set // throws an exception, because zero is an invalid value. // InvokeMember catches the exception, and throws // TargetInvocationException. To discover the real cause // you must catch TargetInvocationException and examine // the inner exception. t.InvokeMember("MyProp",
c# Type.InvokeMember用法
public object InvokeMember(string, BindingFlags, Binder, object, object[]);
string:你所要调用的函数名
BindingFlags:你所要调用的函数的属性,可以组合
Binder:实例
BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new Object[] { 0 }); } catch (TargetInvocationException e) { // If the property assignment failed for some unexpected // reason, rethrow the TargetInvocationException. if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException)) throw; Console.WriteLine("An invalid value was assigned to MyProp."); } t.InvokeMember("MyProp", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty, null, obj, new Object[] { 2 }); v = (Int32)t.InvokeMember("MyProp", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, obj, null); Console.WriteLine("MyProp: " + v); } }
单例模式(Winform窗体的实现)
单例模式(Winform窗体的实现) 在我的设计模式分类当中,我选择单例模式作为我第⼀个要写的设计模式,其⼀,单例模式简单、容易理解让⼈接受,其⼆,单例模式很常⽤,在实际的Winform窗体应⽤开发中能够带来更好的客户体验。
单例模式的核⼼是在应⽤程序的⽣命周期中只实例化⼀次当前类,让整个应⽤整个应⽤程序中只拥有⼀个当前类实例化的对象,在Winform应⽤程序中,我们显⽰窗体的⽅法有两种⽅法:第⼀种,Show()⽅法,这种⽅法当点击多次按钮的时候会显⽰多个当前的窗体,造成操作不便。
第⼆种,ShowDialog()⽅法,这种⽅法显⽰出窗体之后,我们只能对当前窗体进⾏操作直到这个窗体关闭之后,⽤户体验不好。
那怎样才能只产⽣⼀个窗体,⽽且不影响对其他窗体的操作?解决这样的问题我们最简单的想法就是如果每次我们单机按钮都使⽤相同的实例化对象,就只能产⽣⼀个窗体了,再使⽤Show()⽅法显⽰窗体就不会影响其他窗体的操作了。
说了这么多,让我们看看怎么在窗体中使⽤单例模式吧,核⼼参考代码如下:public partial class FrmSingleton : Form{private static FrmSingleton frm = null;private FrmSingleton(){InitializeComponent();}public static FrmSingleton CreateInstrance(){if (frm == null){frm = new FrmSingleton();}return frm;}}FrmSingleton 从上⾯的代码我们可以看出使⽤单例模式有三个重要的要点: (1)构造⽅法⼀定要定义成私有的(这样做的好处就是我们只能在当前类⾥⾯实例化⼀个对象,类外⾯不能实例化,外界想使⽤的话我们可以给它提供⼀个静态⽅法供外界获取) (2)定义⼀个私有的数据类型为当前类的变量(⽤于保证类的实例化对象的唯⼀性) (3)定义⼀个静态的⽅法⽤于给外界提供当前类的实例化对象 上⾯是单例模式使⽤当中应该注意的地⽅,定义好了之后,我们就要在主窗体中的button事件中调⽤它了,具体代码如下:private void button1_Click(object sender, EventArgs e){FrmSingleton FrmSingleton = FrmSingleton.CreateInstrance();FrmSingleton.Show();}button事件调⽤ 好了,⼀个简单的单例模式的Demo就写完了,我们运⾏⼀下应⽤程序,多次点击按钮,也只产⽣⼀个窗体,是不是很有成就感,但是这个时候⼀定不要激动太早,当我们关闭当前打开的窗体之后,再次单机按钮则提⽰我们“⽆法访问已经释放的内存”,其实也很容易解释,当我们关闭窗体时,C#默认的垃圾回收机制会回收我们的frm对象,但此时frm对象并不为null,当我们再次使⽤frm==null进⾏判断时,结果是false,返回出去的是释放内存的frm对象,所以造成这样的结果,那么我们怎么做才能避免异常呢,最简单的做法就是在判断frm==null的地⽅添加⼀个或运算,判断⼀下是否已经释放,如果释放了,我们也要进⾏再次实例化,修改我们刚才的代码,修改后的代码如下:public partial class FrmSingleton : Form{private static FrmSingleton frm = null;private FrmSingleton(){InitializeComponent();}public static FrmSingleton CreateInstrance(){if (frm == null ||frm.IsDisposed){frm = new FrmSingleton();}return frm;}}FrmSingleton 这样我们在运⾏代码,就不会出现我们刚才遇到的问题了,⼀个简单的单例模式这样才算结束,⼜可以愉快的玩耍了。
C#反射简要介绍
反射是.net中的高级功能之一,利用反射可以实现许多以前看来匪夷所思的功能。
一、基本概念反射:反射是一个运行库类型发现的过程。
通过反射可以得到一个给定程序集所包含的所有类型的列表,这个列表包括给定类型中定义的方法、字段、属性和事件。
也可以动态的发现一组给定类支持的借口、方法的参数和其他相关信息如基类、命名空间、数据清单等。
还可以获得每个成员的名称、限定符和参数等。
有了反射,即可对每一个类型了如指掌。
如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。
程序集包含模块,而模块包含类型,类型又包含成员。
反射则提供了封装程序集、模块和类型的对象。
您可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。
然后,可以调用类型的方法或访问其字段和属性。
二、命名空间1.System. Reflection命名空间内的各类型。
Assembly:定义和加载程序集,加载在程序集清单中列出的模块,以及从此程序集中查找类型并创建该类型的实例。
AssemblyName:通过它可以找到大量隐藏在程序集的身份中的信息,如版本信息、区域信息等。
ConstructorInfo:了解以下信息:构造函数的名称、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。
使用 Type 的 GetConstructors 或 GetConstructor 方法来调用特定的构造函数。
EventInfo:事件的信息。
事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等;并添加或移除事件处理程序。
FieldInfo:字段的信息。
字段的名称、访问修饰符(如 public 或private)和实现详细信息(如 static)等;并获取或设置字段值。
MethodInfo:方法的信息。
方法的名称、返回类型、参数、访问修饰符(如 public 或 private)和实现详细信息(如 abstract 或 virtual)等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第一部分:代码(已淘汰,用第三部分) ........................................................................................................................................................................... 1 1、代码: ......................................................................................................................................................................................................................... 1 2、调用方法代码: ......................................................................................................................................................................................................... 2 第二部分:包含注释的代码(已淘汰,用第三部分) ....................................................................................................................................................... 2 1、显示方法代码: ......................................................................................................................................................................................................... 2 2、调用方法代码: ......................................................................................................................................................................................................... 3 第三部分:直接调用的事件委托函数 ................................................................................................................................................................................... 4
第一部分:代码(已淘汰,用第三部分) 1、代码: private void showMdiForm(Type formType) { foreach (Form f in this.MdiChildren) { if (formType.IsInstanceOfType(f)) { f.Activate(); return; } } object formInstance = Activator.CreateInstance(formType, null); System.Reflection.PropertyInfo propertyMdiParent = formType.GetProperty("MdiParent"); propertyMdiParent.SetValue(formInstance, this, null); System.Reflection.MethodInfo methodShow = formType.GetMethod("Show",new Type[]{}); object returnValue = methodShow.Invoke(formInstance, null); } 2、调用方法代码: 设置每个菜单(或工具按钮)的Tag属性为 private void 图书查询ToolStripMenuItem_Click(object sender, EventArgs e) { showMdiForm(typeof(FormTuShuXinXiChaXun)); }
第二部分:包含注释的代码(已淘汰,用第三部分) 1、显示方法代码: /// /// 显示指定类型的子窗体。若尚不存在此类型子窗体,则实例化一个并显示。 /// /// 要显示的子窗体的类型,如typeof(Form1) private void showMdiForm(Type formType) { //遍历主窗体的所有子窗体实例 foreach (Form f in this.MdiChildren) { //判断某子窗体实例f,是否是指定类型的实例 if (formType.IsInstanceOfType(f)) { //若f是指定类型的实例,激活为当前窗体,并结束方法的执行。 f.Activate(); return; } } //利用Activator类(而不是new运算符),创建指定类型的实例,null意为没有构造函数参数。 object formInstance = Activator.CreateInstance(formType, null); //使用反射技术,获取指定类型的MdiParent属性成员 System.Reflection.PropertyInfo propertyMdiParent = formType.GetProperty("MdiParent"); //设置新创建的指定类型的实例的MdiParent属性成员的值为this,null意为MdiParent属性是普通属性(不是索引属性)。 propertyMdiParent.SetValue(formInstance, this, null); //使用反射技术,获取指定类型的Show方法成员。 //"new Type[]{}"意为获取空参数的Show方法,因为Show方法有若干个重载版本,指定参数才能区分它们。 System.Reflection.MethodInfo methodShow = formType.GetMethod("Show",new Type[]{}); //使用MethodInfo对象的Invoke方法,相当于调用对应的方法,Invoke有objec类型返回值。 //此处即调用Show方法,调用新创建的指定类型实例的Show方法,null意为不给Show方法实参。 //此处returnValue没有用,因为Show方法没有返回值。 object returnValue = methodShow.Invoke(formInstance, null); }
2、调用方法代码: private void 图书查询ToolStripMenuItem_Click(object sender, EventArgs e) { //以子窗体的类型为参数,调用自定义方法成员showMdiForm showMdiForm(typeof(FormTuShuXinXiChaXun)); }
private void 填写入库单ToolStripMenuItem_Click(object sender, EventArgs e) { //以子窗体的类型为参数,调用自定义方法成员showMdiForm showMdiForm(typeof(FormTuShuXinXiChaXun)); } 第三部分:直接调用的事件委托函数 private void ToolStripMenuItem_Click(object sender, EventArgs e) { //需静态指定每个ToolStripMenuItem的Tag为对应子窗体的类名 string className = ((ToolStripMenuItem)sender).Tag.ToString(); //根据类名(先转换为类的FullName形式,带命名空间名)得到子窗体的Type Type formType = Type.GetType(this.GetType().Namespace + "." + className); //遍历主窗体的所有子窗体实例 foreach (Form f in this.MdiChildren) { //判断某子窗体实例f,是否是指定类型的实例 if (formType.IsInstanceOfType(f)) { //若f是指定类型的实例,显示为当前窗体(若正最小化,要还原),并结束方法的执行。 if (f.WindowState == FormWindowState.Minimized) f.WindowState =