C# 在C中使用文本框验证事件#

C# 在C中使用文本框验证事件#,c#,winforms,datagridview,C#,Winforms,Datagridview,我有两张表格。主窗体上有一个TextBox,如果我按F1,它将打开一个新窗体,其中包含DataGridView,具体取决于TextBox上插入的值。从第二个表单双击该行后,它将再次转到主表单,并用所选行填充文本框 然后,在主窗体中,我在文本框上有一个验证事件,它将能够根据该值在主窗体DataGridView中显示它 不幸的是,它不起作用,我认为问题来自其他组件的CauseValidation。我禁用了它,例如:dataGridView1.CauseValidation=false,但仍然相同 这

我有两张表格。主窗体上有一个
TextBox
,如果我按
F1
,它将打开一个新窗体,其中包含
DataGridView
,具体取决于
TextBox
上插入的值。从第二个表单双击该行后,它将再次转到主表单,并用所选行填充
文本框

然后,在主窗体中,我在
文本框上有一个验证事件,它将能够根据该值在主窗体
DataGridView
中显示它

不幸的是,它不起作用,我认为问题来自其他组件的
CauseValidation
。我禁用了它,例如:
dataGridView1.CauseValidation=false,但仍然相同

这是
文本框
事件中的代码:

    private void txtCargs_Validating(object sender, CancelEventArgs e)
    {
        e.Cancel = false;
        try
        {
            SqlConnection con = new SqlConnection(cs.DBConnP);
            con.Open();

            string querySelect = @"SELECT RTRIM(CL.Cargs) AS 'Cargs', RTRIM(S.Abvs) AS 'Abss',  RTRIM(CL.Linha) AS 'Linha', RTRIM(CL.Qtd) AS 'Quantity'
                                    FROM CargaCab CC (NOLOCK)
                                    INNER JOIN CargsLin CL (NOLOCK) ON CC.Cargs = CL.Cargs
                                    INNER JOIN Stock S (NOLOCK) ON CL.Code = S.Code 
                                    INNER JOIN Marks M (NOLOCK) ON S.Marks = M.Marks
                                    WHERE CC.Date >= GETDATE() - 120 AND CL.State NOT IN ('F', 'A') AND S.TypeEmb = 'P' 
                                    AND CC.TypeD = 'OCS' AND CL.Cargs = '" + txtCargs.Text.Trim() + "' ORDER BY CL.Carga, S.Marks DESC, S.Abvs";
            cmd = new SqlCommand(querySelect);
            cmd.Connection = con;

            SqlDataAdapter da = new SqlDataAdapter(cmd);

            DataSet ds = new DataSet();
            da.Fill(ds, "CargaCab");

            dataGridView1.DataSource = ds.Tables["CargaCabee"].DefaultView;

            dataGridView1.Columns[0].ReadOnly = true;
            dataGridView1.Columns[1].ReadOnly = true;
            dataGridView1.Columns[2].ReadOnly = true;
            dataGridView1.Columns[3].ReadOnly = false;

            con.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error\nDetalhes: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
我该怎么办?

短期 不要将所有逻辑放在
txtCargs\u Validating
事件中,而是创建一个第二个表单关闭时调用的方法。可以通过将第一个表单的实例传递给第二个表单来实现,例如

public class SecondForm : Form {

  private Form _1stForm;
  public SecondForm(Form 1stForm)
  {
    _1stForm = 1stForm;
  }

从主窗体调用代码:

var frm = new SecondForm(this);
frm.Show();
长期 更好的解决方案是将所有代码放在业务逻辑层中(如MVC中的控制器或MVVM中的ModelView),并将所有UI控件绑定到业务逻辑层中的数据结构

无论哪种方式保存验证事件以进行验证,例如:

 MessageBox.Show("Error\nDetalhes: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

我建议,使用bool返回类型将此事件设置为您的自定义函数。在文本框上使用文本更改事件,然后调用验证函数。我尝试了示例Textbox\u验证事件,并在表单关闭时调用了它。

我认为这里的问题是您希望解决方案得到修复,而不是解决问题

 private void txtCargs_TextChanged(object sender, EventArgs e)
        {
            if (ValidateText())
            {
                //Then do this
            }
        }

        private bool ValidateText()
        {
            bool Isvalidated = false;

            try
            {
                SqlConnection con = new SqlConnection(cs.DBConnP);
                con.Open();

                string querySelect = @"SELECT RTRIM(CL.Cargs) AS 'Cargs', RTRIM(S.Abvs) AS 'Abss',  RTRIM(CL.Linha) AS 'Linha', RTRIM(CL.Qtd) AS 'Quantity'
                                    FROM CargaCab CC (NOLOCK)
                                    INNER JOIN CargsLin CL (NOLOCK) ON CC.Cargs = CL.Cargs
                                    INNER JOIN Stock S (NOLOCK) ON CL.Code = S.Code 
                                    INNER JOIN Marks M (NOLOCK) ON S.Marks = M.Marks
                                    WHERE CC.Date >= GETDATE() - 120 AND CL.State NOT IN ('F', 'A') AND S.TypeEmb = 'P' 
                                    AND CC.TypeD = 'OCS' AND CL.Cargs = '" + txtCargs.Text.Trim() + "' ORDER BY CL.Carga, S.Marks DESC, S.Abvs";
                cmd = new SqlCommand(querySelect);
                cmd.Connection = con;

                SqlDataAdapter da = new SqlDataAdapter(cmd);

                DataSet ds = new DataSet();
                da.Fill(ds, "CargaCab");

                dataGridView1.DataSource = ds.Tables["CargaCabee"].DefaultView;

                dataGridView1.Columns[0].ReadOnly = true;
                dataGridView1.Columns[1].ReadOnly = true;
                dataGridView1.Columns[2].ReadOnly = true;
                dataGridView1.Columns[3].ReadOnly = false;

                con.Close();
                Isvalidated = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error\nDetalhes: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Isvalidated = false;
            }

            return Isvalidated;
        }
以下是我认为如何实现这一目标的简要说明:

public class Form1 : Form
{
    public TextBox textBox1 { get; set; }

    public Button button1 { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        var form = new Form2();
        form.Show();
        textBox1.Text = form.val;
        //do your sql stuff here
    }
}

public class Form2 : Form
{
    public DataGridView datagriview1 { get; set; }

    public string val { get; set; }

    private void datagriview1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex > -1)
            val = datagriview1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
        Close();
    }
}

此代码在什么时候失败?代码没有在断点处运行,为什么要在“验证”事件上执行此操作?正如我所知,当你试图放松对某些控制的关注时,验证就会启动。你不能使用“TextChanged”事件吗?或者事件更好?你不能调用你在文本框中设置值后编写的这个方法吗?不,因为我将写入文本框->按F1键->第二个表单显示->如果第二个表单DataGridView上有记录,我将双击我想要的位置->DataGridView中的值进入主表单文本框->文本框中的值显示在主表单DataGridView@PawełSwajdoWhat中,其中包含更多信息在ValidateText:)上得到的是“//Then do this”),好的,然后用这个ValidateText()替换这个if(ValidateText()){//Then do this};它也不起作用。我在验证事件中使用它,但在de DataGridView中没有显示任何内容“代码未在断点处运行”,您现在至少可以在调试模式下运行它。基本上,我从第二个表单双击datagridview,然后该信息从第一个表单转到TextBox,但不会在第一个表单datagridview上显示假装的信息
public class Form1 : Form
{
    public TextBox textBox1 { get; set; }

    public Button button1 { get; set; }

    private void button1_Click(object sender, EventArgs e)
    {
        var form = new Form2();
        form.Show();
        textBox1.Text = form.val;
        //do your sql stuff here
    }
}

public class Form2 : Form
{
    public DataGridView datagriview1 { get; set; }

    public string val { get; set; }

    private void datagriview1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex > -1)
            val = datagriview1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
        Close();
    }
}