如何将表单加载时间从一种形式减少到另一种形式

时间:2017-12-27 01:23:51

标签: c# winforms

这是我菜单中的代码,单击时会创建另一个表单的实例。

private void btn_AdminReg_Click(object sender, EventArgs e)
{
    this.Hide();
    Admin_Login login = new Admin_Login(1);
    login.Show();
}

它传递一个参数来修改它所使用的登录名(使用相同的登录表单登录多个表单)

在下一个表单中,代码看起来像这样(数据是我已定义的类。它具有连接字符串并从数据库获取数据并插入,更新,删除所有功能)

public partial class Admin_Login : MetroFramework.Forms.MetroForm
{
    int separator; // this is used to separate different logins

    public Admin_Login(int value)
    {
        InitializeComponent();
        separator = value;
    }

    //------- Legend ---------
    //if separator= 1 : AdminTerminal
    //if separator= 2 : UpdatingTerminal
    //if separator= 3 : View Registration
    //if separator= 4 : Registration
    //if separator= 5 : Reports
    //if separator= 6 : Cancel Union

    static string path = Path.GetFullPath(Environment.CurrentDirectory);
    static string dataBaseName = "Trade_Union_Registration.mdf";

    private void btn_Login_Click(object sender, EventArgs e)
    {
        if (separator == 1)
        {
            Data getTable = new Data();
            DataTable table = getTable.GetData("select  UserName,Password from SuperUser where UserName='" + txt_UserName.Text + "' and Password='" + txt_Password.Text + "'");

            if (table.Rows.Count == 1)
            {
                this.Hide();
                TerminalAdmin AdminTerminal = new TerminalAdmin();
                AdminTerminal.Show();
            }
            else
            {
                MetroFramework.MetroMessageBox.Show(this, "Invalid Username/Password please check your Username and Password and try again.", "Access Denied", MessageBoxButtons.OK, MessageBoxIcon.Error);
                txt_Password.Clear();
            }
        }
        else if (separator == 2)
        {
            Data getTable = new Data();
            DataTable table = getTable.GetData("select  UserName,Password from Admin_Table where UserName='" + txt_UserName.Text + "' and Password='" + txt_Password.Text + "'");

            if (table.Rows.Count == 1)
            {
                Data getter = new Data();
                DataTable dt = getter.GetData("select UserID from Admin_Table where UserName='" + txt_UserName.Text + "'");
                MessageBox.Show(dt.Rows[0][0].ToString());
                this.Hide();
                Updating form = new Updating(dt.Rows[0][0].ToString(), txt_UserName.Text);
                form.Show();
            }

当我运行此代码时,我的表单需要花费大量时间将一个表单加载到其他表单。怎么解决这个?

1 个答案:

答案 0 :(得分:1)

首先,我必须同意你的方法(Connacting SQL Queries,普通密码)对于除最原始的学习示例之外的所有人都是有问题的。但我要说它只是一个这样的学习例子。

显示中的任何内容都不会花费很长时间,但很少有代码丢失。我最好的猜测是你在构造函数之间的某个地方做了一些数据库查询并实际显示了Form。在这种情况下,理解"生命周期" Windows窗体表单的格式以及引发任何事件的顺序。不幸的是,我有问题找到像asp.net页面一样的列表。这是我能得到的最接近的: https://docs.microsoft.com/en-us/dotnet/framework/winforms/order-of-events-in-windows-forms

如果在首次显示表单后必须运行任何代码,请将其放入Form.Shown()事件中。这就是现有的目的。

总的来说,您需要某种形式的多任务处理来使这种应用程序工作: 数据库查询,网络操作以及较小程度的磁盘操作非常慢(与代码可以执行的大多数其他操作相比)。任何多任务/ -Threading方法都应该有效:BackgroundWorker,线程,异步......等待模式。

如果不这样做,只需锁定GUI线程即可。对用户来说将是"没有响应"消息,而不是对任何鼠标操作作出反应。

我会:

  • 将一个或多个后台工作程序添加到此表单(每个数据库操作一个)。选择BackgroundWorker,因为它是学习多任务/ - 线程的一个很好的初学者工具。
  • 仅使用按钮启动后台工作人员。不要将实际DB访问代码放在这些按钮后面。如果您将DB访问代码置于后面的按钮,则表单无法响应,直到数据库访问完成或超时。
  • BackgroundWorker完成后将结果放到屏幕上。关于使用数据库访问的进度报告,您无能为力。

多年前我做了一个简单的BackgroundWorker示例。报告的一些内容必须为此删除,但总的来说它仍然应该让你走在正确的轨道上:



#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
	if (!bgwPrim.IsBusy)
	{
		//Prepare ProgressBar and Textbox
		int temp = (int)nudPrim.Value;
		pgbPrim.Maximum = temp;
		tbPrim.Text = "";

		//Start processing
		bgwPrim.RunWorkerAsync(temp);
	}
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
	if (bgwPrim.IsBusy)
	{
		bgwPrim.CancelAsync();
	}
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
	int highestToCheck = (int)e.Argument;
	//Get a reference to the BackgroundWorker running this code
	//for Progress Updates and Cancelation checking
	BackgroundWorker thisWorker = (BackgroundWorker)sender;

	//Create the list that stores the results and is returned by DoWork
	List<int> Primes = new List<int>();
	

	//Check all uneven numbers between 1 and whatever the user choose as upper limit
	for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
	{
		//Report progress
		thisWorker.ReportProgress(PrimeCandidate);
		bool isNoPrime = false;

		//Check if the Cancelation was requested during the last loop
		if (thisWorker.CancellationPending)
		{
			//Tell the Backgroundworker you are canceling and exit the for-loop
			e.Cancel = true;
			break;
		}

		//Determin if this is a Prime Number
		for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
		{
			if (PrimeCandidate % j == 0)
				isNoPrime = true;
		}

		if (!isNoPrime)
			Primes.Add(PrimeCandidate);
	}

	//Tell the progress bar you are finished
	thisWorker.ReportProgress(highestToCheck);

	//Save Return Value
	e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
	pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
	pgbPrim.Value = pgbPrim.Maximum;
	this.Refresh();

	if (!e.Cancelled && e.Error == null)
	{
		//Show the Result
		int[] Primes = (int[])e.Result;

		StringBuilder sbOutput = new StringBuilder();

		foreach (int Prim in Primes)
		{
			sbOutput.Append(Prim.ToString() + Environment.NewLine);
		}

		tbPrim.Text = sbOutput.ToString();
	}
	else 
	{
		tbPrim.Text = "Operation canceled by user or Exception";
	}
}
#endregion
&#13;
&#13;
&#13;