0

我有 2 个课程:MyForm 和 Database

在 MyForm 中,我有一种方法可以更改标签文本以显示错误:

public void printError(string text){
    label1.Text = text;
}

我的 Database 类也需要访问该方法,所以我将其设为静态:

public static void printError(MyForm form, string text){
    form.label1.Text = text;
}

现在的问题是,我如何从 Database 类中调用该方法

我发现的这个问题说我需要像这样将 MyForm 传递给数据库的构造函数:

class MyForm : Form{
    Database db;
    public Form(){
        db = new Database(this);
    }
}

class Database{
    MyForm form;
    public Database(MyForm f){
        form = f;
    }
    ...
    //then I can access the printError like this
    MyForm.printError(form, "You got error");
}

我试过了,它冻结了表格。还有其他解决方案吗?

谢谢

4

4 回答 4

2

就像@Matthew Ferreira 和其他人所说的设计不是想法,但这里有一些东西可以让你开始。

class MyForm : Form
{
    public void SomeMethod()
    {
        var dataAccess = new Repository();

        dataAccess.ExecuteQuery();

        if (dataAccess.Exceptions.Any())
        {
            // display your error messages
            form.label1.Text = dataAccess.Exceptions.Select(x => x.ToString());
        }
    }
}

class Repository
{
    private readonly HashSet<Exception> _exceptions = new HashSet<Exception>();

    public IEnumerable<Exception> Exceptions
    {
        get { return _exceptions; }
    }

    public int ExecuteQuery()
    {
        var numberOfRecordsAffected = 0;

        try
        {
            // do something
        }
        catch (Exception ex)
        {
            // normall catching exceptions is a bad idea
            // and you should really catch the exception at the 
            // layer best equiped to deal with it
            _exceptions.Add(ex);
        }

        // but, for the purpose of this example we might want to add some logic to try the query on another database ????
        try
        {
            // do something
        }
        catch (Exception ex)
        {
            _exceptions.Add(ex);
        }

        return numberOfRecordsAffected;
    }
}
于 2012-08-26T04:15:55.820 回答
2

这是一个非常简单的示例,说明如何在您的数据层不知道您的 UI 的情况下实现此目的:

class MyForm : Form
{
    Database db;

    public Form()
    {
        db = new Database(this);
    }

    public void DoSomething()
    {
        var errors = db.Login("", "");
        if (errors.Any())
            label1.Text = errors.First(); // Or you can display all all of them
    }
}

class Database
{    
    public List<string> Login(string username, string password)
    {
        var errors = new List<string>();

        if (string.IsNullOrEmpty(username))
            errors.Add("Username is required");

        if (string.IsNullOrEmpty(password))
            errors.Add("Password is required");

        [...]

        return errors;
    }
}
于 2012-08-26T04:17:38.287 回答
1

您需要查找“关注点分离”。将您的 UI 代码与数据库访问层 (DAL) 混合在一起真的很糟糕。最好将 UI 绑定到通过 DAL 填充的业务对象。

要让 UI 知道错误,您可以简单地使用委托。

namespace OperationErrorDelegate
{
    public delegate void OperationErrorHandler(Exception ex);

    public class DAL
    {
        public event OperationErrorHandler ReportError;

        public void DoDALOperationThatCausesError()
        {
            try
            {
                int i = 1;
                int j = 0;
                int k = i/j;
            }
            catch (Exception ex)
            {
                ReportError(ex);
            }
        }
    }
}

将此代码添加到表单中:

using System ;
using System.Windows.Forms;

namespace OperationErrorDelegate
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            DAL DAL = new DAL();
            DAL.ReportError += new OperationErrorHandler(DAL_OperationErrorProgress);
            DAL.DoDALOperationThatCausesError();
        }

    private void DAL_OperationErrorProgress(Exception ex)
    {
        label1.Text = ex.Message;
    }
}

}

于 2012-08-26T04:21:45.820 回答
0

假设 OP 的要求是在凭证错误时在标签中显示错误消息:

   private void btn_login_Click(object sender, EventArgs e)
    {
         MySqlConnection con = new MySqlConnection("server=localhost;uid=root;password=abc;database=mydb");
         MySqlCommand cmd = new MySqlCommand("select * from emp where name='" + textBox1.Text + "'and pwd='" + textBox2.Text + "'",con);
         con.Open();
         MySqlDataReader dr = cmd.ExecuteReader();

        if (dr.Read()) 
        {    //successful
            //navigate to next page or whatever you want
        }
        else
            Label1.Text("Invalid userid or password");
        con.Close();
    }

如果需要error message for wrong data type (the user input string but the database column is Integer),请在客户端使用验证。您不需要在后端执行此操作,因为这将是一个负担。您可以在其button_click本身中使用正则表达式。

于 2012-08-26T04:42:16.343 回答