c#窗体传值用法实例详解
本文实例讲述了c#窗体传值用法。分享给大家供大家参考。具体分析如下:
对于窗体间的数据传递,是刚开始从事.Net窗体应用程序开发人员碰到的一个常见问题,在此讲几个常见的实现方式。此节内容适用于模式窗体或非模式窗体,部分方式延伸到一般类的操作。
(1)构造函数参数传递
通过构造函数传递参数应该是比较基本的参数传递方式,重载构造函数,通过带参数的构造函数来实例化窗体。
在窗体类内部定义参数变量,
privateobjectmyParams;
实现构造函数,
publicOptionForm(objectparameters) { InitializeComponent(); this.myParams=parameters;//设置参数引用 }
实例化窗体,
OptionFormform=newOptionForm(myParams);
在实际使用过程中,需要注意传入的是引用类型还是值类型,处理方式会有所不同。
(2)使用窗体的属性
说起属性关联,上面已经提到过Form.Owner属性,下面笔者根据MSDN文档来比较完整的讲一下,大部分的文字来自MSDN文档,为保证其完整性,对其中一些属性描述进行了扩展。
Form.Owner属性。获取或设置拥有此窗体的窗体。
语法,publicFormOwner{get;set;}
若要使某窗体归另一个窗体所有,可为其Owner属性分配一个对将成为所有者的窗体的引用。当一个窗体归另一窗体所有时,它便随着所有者窗体最小化和关闭。例如,如果Form2归窗体Form1所有,则关闭或最小化Form1时,Form2也会关闭或最小化。并且附属窗体从不显示在其所有者窗体后面。可以将附属窗体用于查找和替换窗口之类的窗口,当选定所有者窗体时,这些窗口不应消失。
Form.OwnedForms属性。获取Form对象的数组,这些对象表示此窗体拥有的所有窗体。
语法,publicForm[]OwnedForms{get;}
此属性返回包含此窗体拥有的所有窗体的数组。要使某窗体归另一个窗体所有,可调用AddOwnedForm方法。分配给所有者窗体的窗体将保持被拥有状态,直到调用了RemoveOwnedForm方法。如果窗体是多文档界面(MDI)父窗体,则除了当前打开的所有MDI子窗体外,此属性将返回所有显示的窗体。
Form.MdiChildren属性。获取窗体的数组,这些窗体表示以此窗体作为父级的多文档界面(MDI)子窗体。
语法,publicForm[]MdiChildren{get;}
此属性使您得以获取对当前在某MDI父窗体中打开的所有MDI子窗体的引用。若要创建MDI子窗体,请将要成为MDI父窗体的Form分配给该子窗体的MdiParent属性。可以使用此属性依次通过所有MDI子窗体,以执行一些操作,如当MDI父窗体关闭时将数据保存到数据库中,或者根据应用程序中执行的操作更新子窗体上的字段。
Form.MdiParent属性。获取或设置此窗体的当前多文档界面(MDI)父窗体。
语法,publicFormMdiParent{get;set;}
若要创建MDI子窗体,请将要成为MDI父窗体的Form分配给该子窗体的MdiParent属性。可以从某MDI子窗体使用此属性来获取所有子窗体都需要的全局信息或者调用对所有子窗体执行操作的方法。
Form.ActiveForm静态属性。获取此应用程序的当前活动窗体。
语法,publicstaticFormActiveForm{get;}
表示当前活动窗体,或者如果没有活动窗体,则为空引用。可以使用此方法获得对当前活动窗体的引用,以在该窗体或其控件上执行操作。
Form.ActiveMdiChild属性。获取当前活动的多文档界面(MDI)子窗口。
语法,publicFormActiveMdiChild{get;}
返回表示当前活动的MDI子窗口的Form,或者如果当前没有子窗口,则返回空引用。可使用此方法确定MDI应用程序中是否有任何打开的MDI子窗体。也可使用此方法从MDI子窗口的MDI父窗体或者从应用程序中显示的其他窗体对该MDI子窗口执行操作。
ContainerControl.ParentForm属性。获取将容器控件分配给的窗体。
语法,publicFormParentForm{get;}
将容器控件分配给的Form。
(3)使用公共属性(念时注:我比较常用这种方式)
使用公共属性也是一种比较常用的方式,通过窗体设计器添加的控件默认访问修饰符为private级别,可以设置成public或Internal(在程序集内部可见)来对外公开。比如对窗体中的Button进行公开,那就可以访问Button的相关属性,同时也可以注册事件或撤销事件注册。如:OptionFormform=newOptionForm();
form.buttonOK.Click+=newEventHandler(buttonOK_Click); form.ShowDialog();
对于只允许读取访问或修改访问的控件或变量可以通过属性来控制。对(1)方式进行修改,去除重载构造函数,增加属性也可以实现同样的效果。
publicobjectMyParams { get{returnthis.myParams;} set{this.myParams=value;} }
(4)使用公共方法
使用公共方法类似于属性,对上面的同等实现如下,
//获取参数 publicobjectGetParams() { returnthis.myParams; } //设置参数 publicvoidSetParams(objectmyParams) { this.myParams=myParams; }
(5)使用静态类该方式可以简单的理解为静态变量全局共享,通过下面代码能够比较清楚的理解,先来定义静态类,
publicstaticclassParameterSettings { //公共静态变量 publicstaticstringUsername="Zhengzuo"; //私有静态变量 privatestaticstringuserRole="Administrators"; //私有静态变量 privatestaticstringpassword="https://www.nhooo.com/"; //内部属性 internalstaticstringUserRole { get{returnuserRole;} } //公共属性 publicstaticstringPassword { get{returnpassword;} privateset{password=value;} } }
在需要访问的地方通过以下方式进行:
stringusername=ParameterSettings.Username; stringpassword=ParameterSettings.Password; stringuserRole=ParameterSettings.UserRole; ParameterSettings.Username="郑佐";//修改成新用户名
(6)窗体实现Singleton模式
Singleton模式是我们开发过程中最常用的模式之一。在技术社区经常看到有人谈及对主窗体实现Singleton,但个人认为这不是一种妥当的做法,因为没有这个必要。这里通过另一个自定义类来进行演示。假设UserLoginInfo类用来保存登录系统后的用户凭据。
publicclassUserLoginInfo { //实现Singleton模式,线程安全。 privatereadonlystaticUserLoginInfocurrentUserInfo=newUserLoginInfo(); //提供全局访问点 publicstaticUserLoginInfoCurrentUserInfo { get{returncurrentUserInfo;} } //阻止显式实例化,但不能阻止反射方式调用。 privateUserLoginInfo() { } //公共变量 publicstringUsername; //私有变量 privatestaticstringuserRole; //私有变量 privatestaticstringpassword; //内部属性 internalstringUserRole { get{returnuserRole;} set{userRole=value;} } //公共属性 publicstringPassword { get{returnpassword;} internalset{password=value;} } }
在其他代码中进行访问:
UserLoginInfo.CurrentUserInfo.Username="郑佐"; UserLoginInfo.CurrentUserInfo.UserRole="dotnetlover"; UserLoginInfo.CurrentUserInfo.Password="https://www.nhooo.com/";
对于Singleton模式的实现方式有很多,编写时需要考虑是否需要保证实例访问的线程安全问题,以免引发不可预料的情况,为了提高性能可以考虑惰性实例化。
(7)发布事件进行订阅
通过事件来传递参数应该说是一种推的实现方式,在产生事件时进行被动的获取相关数据。这里将通过一个自定义事件来演示数据的传输。
在自定义事件时,标准的做法都会先定义一个事件参数类,要么直接使用基类EventArgs,或者从EventArgs继承实现自己的参数类,假设自定义基类取名为OptionSettingEventArgs,
//选项设置事件参数类 publicclassOptionSettingEventArgs:EventArgs { privatestringchangedPath; //构造函数 publicOptionSettingEventArgs(stringchangedPath) { this.changedPath=changedPath; } //读取参数 publicstringChangedPath { get{returnthis.changedPath;} } }
以上参数类只包含一个修改后的路径参数。接下去我们要对原先的OptionForm窗体增加事件定义,这里使用.net2.0中提供的泛型类来实现。
//定义事件 publiceventEventHandler<OptionSettingEventArgs>OptionSettingChanged; 编写事件引发程序如下, //引发OptionSettingChanged事件 protectedvirtualvoidOnOptionSettingChanged(OptionSettingEventArgse) { if(OptionSettingChanged!=null) { OptionSettingChanged(this,e); } }
对文件目录选择按钮事件处理程序进行修改来实现事件激发,并没有考虑直接从文本框直接数据输入方式。
//通过目录对话框设置新的路径 privatevoidbuttonBrowser_Click(objectsender,EventArgse) { FolderBrowserDialogdialog=newFolderBrowserDialog(); DialogResultresult=dialog.ShowDialog(this); if(result==DialogResult.OK) { if(this.textBoxPath.Text!=dialog.SelectedPath) { this.textBoxPath.Text=dialog.SelectedPath; OptionSettingEventArgsargs=newOptionSettingEventArgs(dialog.SelectedPath); OnOptionSettingChanged(args); } } }
好了,一切准备工作完成,调用代码如下,
OptionFormform=newOptionForm(); //注册事件 form.OptionSettingChanged+=newEventHandler(form_OptionSettingChanged); form.ShowDialog();
通过以下事件处理程序来验证其正确性,
privatevoidform_OptionSettingChanged(objectsender,OptionSettingEventArgse) { stringnewPath=e.ChangedPath; MessageBox.Show(this,String.Format("新路径为“{0}”。",newPath),"提示"); }
希望本文所述对大家的C#程序设计有所帮助。