0

MyFormとDatabaseの2つのクラスがあります

MyFormには、エラーを表示するようにラベルテキストを変更するメソッドがあります。

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

私のデータベースクラスもそのメソッドにアクセスする必要があるので、静的にします。

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)と混合するのは本当に悪いことです。DALを介して入力されるビジネスオブジェクトにUIをバインドすることをお勧めします。

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 に答える