【问题标题】:Controls.Find not working within specific if-statement?Controls.Find 在特定的 if 语句中不起作用?
【发布时间】:2021-03-30 13:13:57
【问题描述】:

我在使用 controls.find 时遇到问题,但找不到错误。

我正在使用不同的面板创建loginform

面板创建如下:

 public Panel CreatePanel()
    {
        Panel login = new Panel();
        TextBox Login_UsernameTB = new TextBox();
        TextBox Login_PasswordTB = new TextBox();
        Label label1 = new Label();
        Label label2 = new Label();
        Label loginstatus = new Label();
        Button Login_Loginbtn = new Button();
        Button Login_Registerbtn = new Button();
        PictureBox Login_Logo = new PictureBox();
        PictureBox Login_ECard = new PictureBox();


        //creatingPanel
        login.Location = new Point(0, 0);
        login.Name = "Login";
        login.Size = new Size(1000, 400);


        //locations

        Login_ECard.Location = new Point(500, 250);
        Login_ECard.SizeMode = PictureBoxSizeMode.StretchImage;
        Login_ECard.Image = PatientSimulator.Properties.Resources.Ecard;
        Login_ECard.Name = "Login_Ecard";

        Login_Logo.Location = new Point(148, 12);
        Login_Logo.SizeMode = PictureBoxSizeMode.StretchImage;
        Login_Logo.Image = PatientSimulator.Properties.Resources.Logo;
        Login_Logo.Name = "Login_Logo";

        label1.Location = new Point(31, 200);
        label1.Size = new Size(58, 13);
        label1.Text = "Username:";
        label1.Name = "label1";

        label2.Location = new Point(31, 244);
        label2.Size = new Size(56, 13);
        label2.Text = "Password:";
        label2.Name = "label2";

        Login_UsernameTB.Location = new Point(148, 197);
        Login_UsernameTB.Size = new Size(359, 20);
        Login_UsernameTB.Text = "Testfirma1";
        Login_UsernameTB.Name = "Login_UsernameTB";

        Login_PasswordTB.Location = new Point(148, 241);
        Login_PasswordTB.Size = new Size(359, 20);
        Login_PasswordTB.Text = "Hallo1234#";
        Login_PasswordTB.PasswordChar = '*';
        Login_PasswordTB.Name = "Login_PasswordTB";

        Login_Loginbtn.Location = new Point(432, 334);
        Login_Loginbtn.Size = new Size(75, 23);
        Login_Loginbtn.Text = "Login";
        Login_Loginbtn.Click += Login_Loginbtn_Click;
        
        loginstatus.Location = new Point(323, 360);
        loginstatus.Size = new Size(300, 20);
        loginstatus.Text = "";
        loginstatus.Name = "loginstatus";
        
        Login_Registerbtn.Location = new Point(323, 334);
        Login_Registerbtn.Size = new Size(75, 23);
        Login_Registerbtn.Text = "Register";
        Login_Registerbtn.Click += Login_Registerbtn_Click;

        login.Controls.Add(Login_ECard);
        login.Controls.Add(Login_Logo);
        login.Controls.Add(label1);
        login.Controls.Add(label2);
        login.Controls.Add(Login_UsernameTB);
        login.Controls.Add(Login_PasswordTB);
        login.Controls.Add(Login_Loginbtn);
        login.Controls.Add(Login_Registerbtn);
        login.Controls.Add(loginstatus);

        return login;
    }

在 Form_load 中:

    Panel login = CreatePanel();
    login.Visible = true;
    Controls.Add(login);

当我启动应用程序时,所有内容都会显示出来。如果我在systemstatus.text 中输入一些文本,则不会显示。

在检查输入的密码和用户名是否正确时,会发生奇怪的事情。

private void Login_Loginbtn_Click(object sender, EventArgs e)
    {
        Patient.DBAccess db = new Patient.DBAccess();
        Sha256 sha = new Sha256();
        string username = login.Controls.Find("Login_UsernameTB", true)[0].Text;
        string userpw = login.Controls.Find("Login_PasswordTB", true)[0].Text;            

        Patient.DatabaseRequestInterface.UserInterface user = new Patient.DatabaseRequestInterface.UserInterface();
        user.Username = username;
                   

        if (db.IsUserExisting(user)){
            user = db.ReadUserPassword(user);
            string salt = Encoding.ASCII.GetString(user.PasswordSalt);
            byte[] pw = sha.GetSha256(userpw, salt);

            if (pw.SequenceEqual(user.PasswordHash))
            {
                //Programm starten
                //token generieren
                Patient.DatabaseRequestInterface.UserInterface useri = db.ReadFullUser(user);

                UserAuthentificationToken = new UserInfo(useri.Username, useri.Uuid, DateTime.Now);
                LoginSuccessEvent?.Invoke(this, new EventArgs());
                
                login.Controls.Find("loginstatus", true)[0].Text = "Login successfull";

                this.Close();
            }
            else
            {
                MessageBox.Show("Login failed, Username and/or password incorrect");
            }
        
        }
        else
        {
            MessageBox.Show("Falscher User oder Passwort");
            //Controls.Find("Login_StatusL", true)[0].Text = "Login failed, Username and/or password incorrect!";
        }
    }

我使用controls.find 的前 2 次有效,我得到了用户在相应的TextBoxes 输入的字符串。当我尝试更改loginstatus 时,我得到了System.IndexOutOfRangeException。我对异常的解释是,没有找到loginstatus。我不明白为什么。 (在 if 中也找不到其他 2 个元素) 有人可以帮忙吗?

controls.find("string",true)[0].Text = "XXX" 有效,我在应用程序的另一部分经常使用它

有什么想法吗? 提前致谢, 大卫

【问题讨论】:

  • 我的答案已经更新了更多细节
  • 构建一个 UserControl 并公开返回您需要的值并允许设置内部控件状态的公共属性。

标签: c# forms controls


【解决方案1】:

您错过了代码中的Name 属性,而Controls.Find 严格使用Name

    Login_UsernameTB.Name = "Login_UsernameTB";

所以你的代码应该是这样的:

    public Panel CreatePanel()
    {
        Panel login = new Panel();

        login.Size = new Size(900, 900);

        TextBox Login_UsernameTB = new TextBox();
        Login_UsernameTB.Name = "Login_UsernameTB";
        Login_UsernameTB.Location = new Point(50, 50);
        Login_UsernameTB.Text = "Username here";


        TextBox Login_PasswordTB = new TextBox();
        Login_PasswordTB.Name = "Login_PasswordTB";
        Login_PasswordTB.Location = new Point(150, 50);
        Login_PasswordTB.Text = "password here";

        //stuff is asigned to TBs...

        Label loginstatus = new Label();
        loginstatus.Location = new Point(150, 150);
        loginstatus.Size = new Size(300, 20);
        loginstatus.Text = "";
        loginstatus.Name = "loginstatus";


        login.Controls.Add(Login_UsernameTB);
        login.Controls.Add(Login_PasswordTB);
        login.Controls.Add(loginstatus);

        return login;
    }

另外,login 应该是类级别,但未在 Form_Load 中定义 像这样:

public partial class Form1 : Form
{

    Panel login;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        login = CreatePanel();
        login.Visible = true;
        Controls.Add(login);
    }
    .....

我已经测试过了,效果很好。

我的测试代码是

using System;
using System.Drawing;
using System.Windows.Forms;

namespace SackOverflow
{
    public partial class Form1 : Form
    {

        Panel login;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            login = CreatePanel();
            login.Visible = true;
            Controls.Add(login);
        }

        public Panel CreatePanel()
        {
            Panel login = new Panel();

            login.Size = new Size(900, 900);

            TextBox Login_UsernameTB = new TextBox();
            Login_UsernameTB.Name = "Login_UsernameTB";
            Login_UsernameTB.Location = new Point(50, 50);
            Login_UsernameTB.Text = "Username";


            TextBox Login_PasswordTB = new TextBox();
            Login_PasswordTB.Name = "Login_PasswordTB";
            Login_PasswordTB.Location = new Point(150, 50);
            Login_PasswordTB.Text = "password";

            //stuff is asigned to TBs...

            Label loginstatus = new Label();
            loginstatus.Location = new Point(150, 150);
            loginstatus.Size = new Size(300, 20);
            loginstatus.Text = "";
            loginstatus.Name = "loginstatus";


            login.Controls.Add(Login_UsernameTB);
            login.Controls.Add(Login_PasswordTB);
            login.Controls.Add(loginstatus);

            return login;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (true)
            {
                string username = login.Controls.Find("Login_UsernameTB", true)[0].Text;
                string userpw = login.Controls.Find("Login_PasswordTB", true)[0].Text;

                //UserInterface user = //some database stuff to get the password saved by the user

                if ("123" == userpw)
                {
                    login.Controls.Find("loginstatus", true)[0].Text = "Logging in";
                    Login();
                }
                else
                {
                    login.Controls.Find("loginstatus", true)[0].Text = "Error";
                }
            }
        }

        private void Login()
        {
            MessageBox.Show("Login");
        }
    }
}

结果是: 我收到消息框MessageBox.Show("Login");显示Loginstatus显示

【讨论】:

  • 问题不在于文本框,我跳过了那部分,因为它与问题无关,但我的方式与您的方式相同,因为这很奇怪,我仍然得到错误。出于好奇,我将登录状态的 control.find 移到 if(UserExists()) 上方,它在那里工作。然后我把它移到了 if(user.pw == userpw) 的正上方,它也在那里工作。所以第二个 if 似乎是问题所在。知道为什么吗?
  • @Murf 你把面板放在类级别了吗?
  • @Murf 我没有看到我的测试代码与您在问题中发布的代码相似,请好好比较一下。我已将Panel 的定义移动到class 级别,并将Name 属性添加到控件中,它工作正常,而它在开始时给出相同的Exception
  • 我刚刚又查了一下,代码基本一样。如前所述,它在第二个 if 之外起作用,如果我得到错误,它只在第二个内部起作用。这真是令人沮丧:(
  • @Murf 能否请您在更新后在评论中再次发布您在问题中提到的代码部分(如果适用)
猜你喜欢
  • 2017-05-22
  • 1970-01-01
  • 2012-07-16
  • 2021-04-23
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
  • 2016-04-25
  • 1970-01-01
相关资源
最近更新 更多