Form学习总结

  • 格式:pdf
  • 大小:162.87 KB
  • 文档页数:19

Form学习总结

Form问题

如何控制窗体的显⽰顺序

很多编程者常常会遇到这样的现象,例如,通过⼀个登录窗体去打开⼀个主窗体,然后要在主窗体中想关闭这个登录窗体。那么就有⼈出主意,你可以在打开主窗体的时候把登录窗体⾃⾝传进去,然后在主窗体中调⽤它的Hide⽅法来隐藏。虽说这样可以暂时达到你所要的效果,但不是最合理的解决办法。因为这样做有如下两个缺陷。

第⼀个就是,登录窗体已经完成使命,⽽资源没有得到及时释放;

其次就是,在窗体关闭的时候⽐较⿇烦,需要找到登录窗⼝,关闭⾃⾝的同时要关闭登录窗体。

遇到此问题的时候,⾸要的是分析窗体打开的顺序以及相互关联的条件,常见的类型⽆⾮就是主⼦或者先后这两种。理解好第⼀点后,那么要学会合理使⽤ShowDialog和DialogResult 这两个好东西,前者属于模式打开窗体,后者属于窗体的返回值。

明⽩了这两点,就可以很⽅便的解决类似于登录窗体的问题,这⽅⾯的例⼦可以参看我的这篇⽂章。

具体做法如下:

⾸先,创建Login窗⼝,然后添加相应的输⼊框和按钮,设置窗⼝的AcceptButton为窗体的确认按钮,⽽CancelButton为窗体的取消按钮。例如:this.AcceptButton = this.btnOK;

this.CancelButton = this.btnCancel;

定义确定按钮以及取消按钮事件,如下:private void btnOK_Click(object sender, System.EventArgs e)

{

// Here is to use fixed username and password

// You can check username and password from DB

if( txtUserName.Text == "Admin" && txtPassword.Text == "nopassword" )

{

// Save login user info

http://www.doczj.com/doc/b64dde0e581b6bd97f19eaaa.html erName = txtUserName.Text;

uiLogin.Password = txtPassword.Text;

// Set dialog result with OK

this.DialogResult = DialogResult.OK;

}

else

{

// Wrong username or password

nLoginCount++;

if( nLoginCount == MAX_LOGIN_COUNT )

// Over 3 times

this.DialogResult = DialogResult.Cancel;

else{

MessageBox.Show( "Invalid user name and password!" );

txtUserName.Focus();

}

}

}

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

{

// Set dialog result with Cancel

this.DialogResult = DialogResult.Cancel;

}

然后,在Login窗体的Closing事件中,要进⾏处理,如下:private void frmLogin_Closing(object sender, http://www.doczj.com/doc/b64dde0e581b6bd97f19eaaa.htmlponentModel.CancelEventArgs e) {

// Check whether form is closed with dialog result

if( this.DialogResult != DialogResult.Cancel &&

this.DialogResult != DialogResult.OK )

e.Cancel = true;

}

除此外,Login窗体⼀些辅助代码如下:private int nLoginCount = 0;

private const int MAX_LOGIN_COUNT = 3;

private UserInfo uiLogin;

public frmLogin( ref UserInfo ui )

{

//

// Required for Windows Form Designer support

//

InitializeComponent();

// Set login info to class member

uiLogin = ui;

}

调⽤的时候,要修改程序的Main函数,如下:///

/// The main entry point for the application.

///[STAThread]

static void Main()

{

UserInfo ui = new UserInfo();

frmLogin myLogin = new frmLogin( ref ui );

if( myLogin.ShowDialog() == DialogResult.OK )

{

//Open your main form here

MessageBox.Show( "Logged in successfully!" ); }

else

{

MessageBox.Show( "Failed to logged in!" );

}

}

⽽附加的UserInfo类如下:///

/// User info class

///

public class UserInfo

{

private string strUserName;

private string strPassword;

public string UserName

{

get{ return strUserName;}

set{ strUserName = value; }

}

public string Password

{

get{ return strPassword;}

set{ strPassword = value;}

}

public UserInfo()

{

strUserName = "";strPassword = "";

}

}

窗体之间的对象如何相互引⽤或者操作

常见的类似问题有:1.如何在⼦窗体访问到主窗体中的某某数据;

2.如何在⼦窗体中调⽤主窗体中的某某⽅法;

3.如何在⼦窗体关闭的时候去更新主窗体的某某数据;

对于如上的三个问题,完全可以由如下两种⽅法来完成。1.当数据是⼦窗体显⽰的必要条件的话,通过修改⼦窗体的构造函数来进⾏传递数据;2.如果是不定时的访问,则可以通过委托来实现。

对于第⼀点,我就不多说了,对于第⼆点,我⽤如下的例⼦来说明。

⾸先在⼦窗体中,需要如下://Define two delegate methods to get or set textbox value in main form

public delegate void SetTextV alue( string TextV alue );

public delegate string GetTextV alue( );

// In sub-form class

// Handler for methods from main form

private SetTextV alue SetText = null;

private GetTextV alue GetText = null;

// Call methods as follows

string strV alue = GetText();

SetText( strV alue + DateTime.Now.ToString() );

除了如上⼀些操作外,还需要修改⼦窗体的构造函数,来接收这两个delegate⽅法,这⾥就不多说了。

⾄于主窗体,⾸先要为这两个委托来实现对应函数,例如:///

/// Get textbox's text for other forms

///

///

private string GetV alue()

{

return yourTextBox.Text;

}

///

/// Set textbox's text for other forms

//////

private void SetV alue( string sV alue )

{

yourTextBox.Text = sV alue;

}

那么调⽤⼦窗体的时候就⽐较简单了。// Create subform and show it

yourSubForm myForm = new yourSubForm(

new SetTextV alue( SetV alue ),

new GetTextV alue( GetV alue ) );

myForm.ShowDialog();

这样⼀个通过委托来操纵主窗体的例⼦就完成了。这⾥需要注意的⼀点,如果在⼦窗体中⼤量使⽤到主窗体的数据的话,那我建议你重新考虑窗体架构,这意味着你⽬前的窗体架构不

合理。

窗体的唯⼀性问题

使⽤Mutex来进⾏1.⾸先要添加如下的namespace:

using System.Threading;

2.修改系统Main函数,⼤致如下:

bool bCreatedNew;

//Create a new mutex using specific mutex name

Mutex m =new Mutex( false, "myUniqueName", out bCreatedNew );

if( bCreatedNew )

Application.Run(new yourFormName());

如上⾯编码就可以了,要注意的⼀点是,在给Mutex起名字的时候,不要太简单,以防⽌和其他程序的Mutex重复,从⽽达不到所预想的效果。

使⽤Process来进⾏1.⾸先要添加如下的namespace:

using System.Diagnostics;

using System.Reflection;

2.添加如下函数:

public static Process RunningInstance()

{

Process current = Process.GetCurrentProcess();

Process[] processes = Process.GetProcessesByName(current.ProcessName);

//Loop through the running processes in with the same name