简体   繁体   English

如何通过 C# 中的事件处理程序将 class 的实例传回

[英]How do I pass an instance of a class back through an Event Handler in C#

So I am just getting my head around how Event Handlers work.所以我只是想了解事件处理程序是如何工作的。

I have a WinForms app which has a panel control on the main form.我有一个 WinForms 应用程序,它在主窗体上有一个面板控件。 I fill the panel with a login page.我用登录页面填充面板。 The login page will search the DB for the user and check the password is correct when the user clicks the login button.当用户单击登录按钮时,登录页面将在数据库中搜索用户并检查密码是否正确。 Providing the login details are correct, it then triggers the event handler to tell the main form the login was successful.如果登录详细信息正确,它会触发事件处理程序告诉主窗体登录成功。 It should then store the Users details in the main form ready for when the panel is filled with the next control.然后它应该将用户详细信息存储在主窗体中,以便在面板填充下一个控件时做好准备。 When the user logs in, it creates an instance of a class called User.当用户登录时,它会创建一个名为 User 的 class 实例。 How can I pass that User back to the main form so it knows which user is currently logged in?如何将该用户传递回主窗体,以便它知道当前登录的用户?

I hope this makes sense.我希望这是有道理的。

This is in the ctrl:这是在 ctrl 中:

public partial class ctrlLoginPage : UserControl
{
    public event EventHandler RegisterButtonClicked;
    public event EventHandler LoginButtonClicked;
    public User activeUser = new User();
    public ctrlLoginPage()
    {
        InitializeComponent();
    }

    private void btnRegister_Click(object sender, EventArgs e)
    {
        RegisterButtonClicked(this, e);
    }

    public void btnLogon_Click(object sender, EventArgs e)
    {
        SqlConnection con = new SqlConnection();
        con.ConnectionString = "server=DESKTOP-05NVBR2\\SQLEXPRESS;database=GymAppPrototype;UID=sa;password=Mabg123";
        con.Open();

        SqlDataReader dataReader = null;
        SqlCommand myCommand = new SqlCommand("select * from Customer where Email ='" + txtEmail.Text + "';", con);
        dataReader = myCommand.ExecuteReader();
        while (dataReader.Read())
        {
            activeUser.forename = dataReader["Forename"].ToString();
            activeUser.surname = dataReader["Surname"].ToString();
            activeUser.email = dataReader["Email"].ToString();
            activeUser.password = dataReader["Password"].ToString();
            activeUser.mobile = dataReader["MobileNumber"].ToString();
        }
        con.Close();
        if (txtPassword.Text == activeUser.password)
        {
            MessageBox.Show("Login Successful");
            LoginButtonClicked(this, e);
        }
        else
        {
            MessageBox.Show("Login Failed");
        }
        
    }
   
}

It all depends on the way you design your classes and their integration but given the example above you can use a custom EventArgs or better yet a custom EventHandler.这完全取决于您设计类及其集成的方式,但鉴于上面的示例,您可以使用自定义 EventArgs 或更好的是自定义 EventHandler。

Don't pass 'e' to the 'LoginButtonClicked' event.不要将“e”传递给“LoginButtonClicked”事件。 Instead use custom event args class containing logged in user data.而是使用包含登录用户数据的自定义事件参数 class。 For that you need to define your event handler a tab bit different though:为此,您需要为您的事件处理程序定义一个有点不同的选项卡:

event EventHandler<MyEventArgs> LoginButtonClicked;

Then define your event args class:然后定义您的事件参数 class:

public class MyEventArgs : EventArgs{
public MyEventArgs(User activeUser) {
    ActiveUser = activeUser;
}
  public User ActiveUser { get; }
}

Now you can pass a new instance of the new class instead of 'e':现在您可以传递新的 class 的新实例而不是“e”:

LoginButtonClicked(this, new MyEventArgs(activeUser));

The subscriber of the event can then use e.ActiveUser to access the logged in user info, for example:然后事件的订阅者可以使用 e.ActiveUser 访问登录的用户信息,例如:

myLoginPanel.LoginButtonClicked += (s, e) => { /* do something with e.ActiveUser */ };

While it's entirely possible to use the standard event-based messaging in your application, I would question whether it's even necessary here.虽然完全可以在您的应用程序中使用标准的基于事件的消息传递,但我会怀疑这里是否有必要。 Depending on your workflow, it might be simplest to show a different form and block until the user logs in/registers, or cancels it:根据您的工作流程,显示不同的表单并阻止直到用户登录/注册或取消它可能是最简单的:

//MainForm
public void GetUser()
{
    using var userWindow = new UserForm();
    if (userWindow.ShowDialog(this) == DialogResult.OK)
    {
        return userWindow.SelectedUser;
    }

    return null;
}
//UserForm
public class UserForm : Form
{
    public User SelectedUser { get; private set; }

    private void btnRegister_Click(object sender, EventArgs e)
    {
        SelectedUser = // registration logic

        DialogResult = DialogResult.OK;

        Close();
    }

    private void btnLogon_Click(object sender, EventArgs e)
    {
        SelectedUser = // logon logic

        DialogResult = DialogResult.OK;

        Close();
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        DialogResult = DialogResult.Cancel;

        Close();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM